Skip to content

Commit 9e93257

Browse files
opacaminclement
authored andcommitted
[recipe-stl] Rework of libtorrent and boost (#1971)
which: - fix build for android's NDK r19+ - allow us to build `boost+libtorrent` for any arch - Update boost to version `1.69.0` - update libtorrent to version `1.2.1` The build method needs to be changed because one of the scripts used in `boost+libtorrent` build (make-standalone-toolchain.sh), has been removed from android's NDK. [This is because](https://developer.android.com/ndk/guides/standalone_toolchain): `As of r19, the NDK's default toolchains are standalone toolchains, which renders this process unnecessary.` Note: since 3887d2b, `python-for-android` uses android's NDK r19 as the minimum supported and also changed the build method used by p4a as [described in here](https://developer.android.com/ndk/guides/other_build_systems)
1 parent dfad9c0 commit 9e93257

File tree

5 files changed

+135
-117
lines changed

5 files changed

+135
-117
lines changed

pythonforandroid/recipes/boost/__init__.py

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory
1+
from pythonforandroid.util import current_directory, build_platform
2+
from pythonforandroid.recipe import Recipe
3+
from pythonforandroid.logger import shprint
24
from os.path import join, exists
35
from os import environ
6+
import shutil
47
import sh
58

69
"""
7-
This recipe creates a custom toolchain and bootstraps Boost from source to build Boost.Build
10+
This recipe bootstraps Boost from source to build Boost.Build
811
including python bindings
912
"""
1013

1114

1215
class BoostRecipe(Recipe):
1316
# Todo: make recipe compatible with all p4a architectures
1417
'''
15-
.. note:: This recipe can be built only against API 21+ and arch armeabi-v7a
18+
.. note:: This recipe can be built only against API 21+ and an android
19+
ndk >= r19
1620
1721
.. versionchanged:: 0.6.0
1822
Rewrote recipe to support clang's build. The following changes has
@@ -24,22 +28,33 @@ class BoostRecipe(Recipe):
2428
- Default compiler for ndk's toolchain set to clang
2529
- Python version will be detected via user-config.jam
2630
- Changed stl's lib from ``gnustl_shared`` to ``c++_shared``
31+
32+
.. versionchanged:: 2019.08.09.1.dev0
33+
34+
- Bumped version number to 1.68.0
35+
- Adapted to work with ndk-r19+
2736
'''
28-
version = '1.68.0'
29-
url = 'http://downloads.sourceforge.net/project/boost/' \
30-
'boost/{version}/boost_{version_underscore}.tar.bz2'
37+
version = '1.69.0'
38+
url = (
39+
'http://downloads.sourceforge.net/project/boost/'
40+
'boost/{version}/boost_{version_underscore}.tar.bz2'
41+
)
3142
depends = [('python2', 'python3')]
32-
patches = ['disable-so-version.patch',
33-
'use-android-libs.patch',
34-
'fix-android-issues.patch']
43+
patches = [
44+
'disable-so-version.patch',
45+
'use-android-libs.patch',
46+
'fix-android-issues.patch',
47+
]
48+
need_stl_shared = True
3549

3650
@property
3751
def versioned_url(self):
3852
if self.url is None:
3953
return None
4054
return self.url.format(
4155
version=self.version,
42-
version_underscore=self.version.replace('.', '_'))
56+
version_underscore=self.version.replace('.', '_'),
57+
)
4358

4459
def should_build(self, arch):
4560
return not exists(join(self.get_build_dir(arch.arch), 'b2'))
@@ -48,56 +63,50 @@ def prebuild_arch(self, arch):
4863
super(BoostRecipe, self).prebuild_arch(arch)
4964
env = self.get_recipe_env(arch)
5065
with current_directory(self.get_build_dir(arch.arch)):
51-
if not exists(env['CROSSHOME']):
52-
# Make custom toolchain
53-
bash = sh.Command('bash')
54-
shprint(bash, join(self.ctx.ndk_dir, 'build/tools/make-standalone-toolchain.sh'),
55-
'--arch=' + env['ARCH'],
56-
'--platform=android-' + str(self.ctx.android_api),
57-
'--toolchain=' + env['CROSSHOST'] + '-' + self.ctx.toolchain_version + ':-llvm',
58-
'--use-llvm',
59-
'--stl=libc++',
60-
'--install-dir=' + env['CROSSHOME']
61-
)
6266
# Set custom configuration
63-
shutil.copyfile(join(self.get_recipe_dir(), 'user-config.jam'),
64-
join(env['BOOST_BUILD_PATH'], 'user-config.jam'))
67+
shutil.copyfile(
68+
join(self.get_recipe_dir(), 'user-config.jam'),
69+
join(env['BOOST_BUILD_PATH'], 'user-config.jam'),
70+
)
6571

6672
def build_arch(self, arch):
6773
super(BoostRecipe, self).build_arch(arch)
6874
env = self.get_recipe_env(arch)
6975
env['PYTHON_HOST'] = self.ctx.hostpython
7076
with current_directory(self.get_build_dir(arch.arch)):
71-
# Compile Boost.Build engine with this custom toolchain
72-
bash = sh.Command('bash')
73-
shprint(bash, 'bootstrap.sh') # Do not pass env
74-
# Install app stl
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'))
79-
80-
def select_build_arch(self, arch):
81-
return arch.arch.replace('eabi-v7a', '').replace('eabi', '')
77+
if not exists('b2'):
78+
# Compile Boost.Build engine with this custom toolchain
79+
bash = sh.Command('bash')
80+
shprint(bash, 'bootstrap.sh') # Do not pass env
8281

8382
def get_recipe_env(self, arch):
8483
# We don't use the normal env because we
8584
# are building with a standalone toolchain
8685
env = environ.copy()
8786

88-
env['BOOST_BUILD_PATH'] = self.get_build_dir(arch.arch) # find user-config.jam
89-
env['BOOST_ROOT'] = env['BOOST_BUILD_PATH'] # find boost source
87+
# find user-config.jam
88+
env['BOOST_BUILD_PATH'] = self.get_build_dir(arch.arch)
89+
# find boost source
90+
env['BOOST_ROOT'] = env['BOOST_BUILD_PATH']
9091

9192
env['PYTHON_ROOT'] = self.ctx.python_recipe.link_root(arch.arch)
9293
env['PYTHON_INCLUDE'] = self.ctx.python_recipe.include_root(arch.arch)
9394
env['PYTHON_MAJOR_MINOR'] = self.ctx.python_recipe.version[:3]
94-
env['PYTHON_LINK_VERSION'] = self.ctx.python_recipe.major_minor_version_string
95+
env[
96+
'PYTHON_LINK_VERSION'
97+
] = self.ctx.python_recipe.major_minor_version_string
9598
if 'python3' in self.ctx.python_recipe.name:
9699
env['PYTHON_LINK_VERSION'] += 'm'
97100

98-
env['ARCH'] = self.select_build_arch(arch)
99-
env['CROSSHOST'] = env['ARCH'] + '-linux-androideabi'
100-
env['CROSSHOME'] = join(env['BOOST_ROOT'], 'standalone-' + env['ARCH'] + '-toolchain')
101+
env['ARCH'] = arch.arch.replace('-', '')
102+
env['TARGET_TRIPLET'] = arch.target
103+
env['CROSSHOST'] = arch.command_prefix
104+
env['CROSSHOME'] = join(
105+
self.ctx.ndk_dir,
106+
'toolchains/llvm/prebuilt/{build_platform}'.format(
107+
build_platform=build_platform
108+
),
109+
)
101110
return env
102111

103112

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
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
1+
diff -u -r boost_1_69_0.orig/boost/asio/detail/config.hpp boost_1_69_0/boost/asio/detail/config.hpp
2+
--- boost_1_69_0.orig/boost/asio/detail/config.hpp 2018-12-05 20:58:15.000000000 +0100
3+
+++ boost_1_69_0/boost/asio/detail/config.hpp 2018-12-13 14:52:06.000000000 +0100
4+
@@ -815,7 +815,11 @@
5+
# if (_LIBCPP_VERSION < 7000)
6+
# if (__cplusplus >= 201402)
7+
# if __has_include(<experimental/string_view>)
8+
-# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
9+
+# if __clang_major__ >= 7
10+
+# undef BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW
11+
+# else
12+
+# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
13+
+# endif // __clang_major__ >= 7
14+
# endif // __has_include(<experimental/string_view>)
15+
# endif // (__cplusplus >= 201402)
16+
# endif // (_LIBCPP_VERSION < 7000)
17+
diff -u -r boost_1_69_0.orig/boost/config/user.hpp boost_1_69_0/boost/config/user.hpp
18+
--- boost_1_69_0.orig/boost/config/user.hpp 2018-12-05 20:58:16.000000000 +0100
19+
+++ boost_1_69_0/boost/config/user.hpp 2018-12-13 14:35:29.000000000 +0100
420
@@ -13,6 +13,12 @@
521
// configuration policy:
622
//
7-
23+
824
+// Android defines
925
+// There is problem with std::atomic on android (and some other platforms).
1026
+// See this link for more info:
@@ -13,41 +29,25 @@ diff -u -r boost_1_68_0.orig/boost/config/user.hpp boost_1_68_0/boost/config/use
1329
+
1430
// define this to locate a compiler config file:
1531
// #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>
32+
33+
diff -u -r boost_1_69_0.orig/boost/system/error_code.hpp boost_1_69_0/boost/system/error_code.hpp
34+
--- boost_1_69_0.orig/boost/system/error_code.hpp 2018-12-05 20:58:23.000000000 +0100
35+
+++ boost_1_69_0/boost/system/error_code.hpp 2018-12-13 14:53:33.000000000 +0100
36+
@@ -14,6 +14,7 @@
37+
#include <boost/system/detail/config.hpp>
38+
#include <boost/cstdint.hpp>
39+
#include <boost/config.hpp>
4040
+#include <stdio.h>
4141
#include <ostream>
4242
#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
43+
#include <functional>
44+
diff -u -r boost_1_69_0.orig/libs/filesystem/src/operations.cpp boost_1_69_0/libs/filesystem/src/operations.cpp
45+
--- boost_1_69_0.orig/libs/filesystem/src/operations.cpp 2018-12-05 20:58:17.000000000 +0100
46+
+++ boost_1_69_0/libs/filesystem/src/operations.cpp 2018-12-13 14:55:41.000000000 +0100
4747
@@ -232,6 +232,21 @@
48-
48+
4949
# if defined(BOOST_POSIX_API)
50-
50+
5151
+# if defined(__ANDROID__)
5252
+# define truncate libboost_truncate_wrapper
5353
+// truncate() is present in Android libc only starting from ABI 21, so here's a simple wrapper
@@ -64,5 +64,23 @@ diff -u -r boost_1_68_0.orig/libs/filesystem/src/operations.cpp boost_1_68_0/lib
6464
+# endif
6565
+
6666
typedef int err_t;
67-
67+
6868
// POSIX uses a 0 return to indicate success
69+
diff -u -r boost_1_69_0.orig/tools/build/src/tools/common.jam boost_1_69_0/tools/build/src/tools/common.jam
70+
--- boost_1_69_0.orig/tools/build/src/tools/common.jam 2019-01-25 23:18:34.544755629 +0200
71+
+++ boost_1_69_0/tools/build/src/tools/common.jam 2019-01-25 23:20:42.309047754 +0200
72+
@@ -976,10 +976,10 @@
73+
}
74+
75+
# Ditto, from Clang 4
76+
- if $(tag) in clang clangw && [ numbers.less 3 $(version[1]) ]
77+
- {
78+
- version = $(version[1]) ;
79+
- }
80+
+ #if $(tag) in clang clangw && [ numbers.less 3 $(version[1]) ]
81+
+ #{
82+
+ # version = $(version[1]) ;
83+
+ #}
84+
85+
# On intel, version is not added, because it does not matter and it is the
86+
# version of vc used as backend that matters. Ideally, we should encode the

pythonforandroid/recipes/boost/user-config.jam

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,30 @@
11
import os ;
22

33
local ARCH = [ os.environ ARCH ] ;
4+
local TARGET_TRIPLET = [ os.environ TARGET_TRIPLET ] ;
45
local CROSSHOME = [ os.environ CROSSHOME ] ;
56
local PYTHON_HOST = [ os.environ PYTHON_HOST ] ;
67
local PYTHON_ROOT = [ os.environ PYTHON_ROOT ] ;
78
local PYTHON_INCLUDE = [ os.environ PYTHON_INCLUDE ] ;
89
local PYTHON_LINK_VERSION = [ os.environ PYTHON_LINK_VERSION ] ;
910
local PYTHON_MAJOR_MINOR = [ os.environ PYTHON_MAJOR_MINOR ] ;
1011

11-
using clang : $(ARCH) : $(CROSSHOME)/bin/arm-linux-androideabi-clang++ :
12-
<archiver>$(CROSSHOME)/bin/arm-linux-androideabi-ar
13-
<root>$(CROSSHOME)/sysroot
14-
<architecture>$(ARCH)
15-
<compileflags>-fexceptions
16-
<compileflags>-frtti
17-
<compileflags>-fpic
12+
using clang : $(ARCH) : $(CROSSHOME)/bin/$(TARGET_TRIPLET)-clang++ :
13+
<archiver>$(CROSSHOME)/bin/llvm-ar
14+
<compileflags>-fPIC
1815
<compileflags>-ffunction-sections
16+
<compileflags>-fdata-sections
1917
<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
18+
<compileflags>-fstack-protector-strong
19+
<compileflags>-no-canonical-prefixes
20+
<compileflags>-Wformat
21+
<compileflags>-Werror=format-security
22+
<compileflags>-frtti
23+
<compileflags>-fexceptions
24+
<compileflags>-DNDEBUG
3725
<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
26+
<compileflags>-Oz
27+
<compileflags>-mthumb
4728
<linkflags>-Wl,-z,relro
4829
<linkflags>-Wl,-z,now
4930
<linkflags>-lc++_shared

pythonforandroid/recipes/libtorrent/__init__.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import sh
66

77
# This recipe builds libtorrent with Python bindings
8-
# It depends on Boost.Build and the source of several Boost libraries present in BOOST_ROOT,
9-
# which is all provided by the boost recipe
8+
# It depends on Boost.Build and the source of several Boost libraries present
9+
# in BOOST_ROOT, which is all provided by the boost recipe
1010

1111

1212
def get_lib_from(search_directory, lib_extension='.so'):
@@ -24,7 +24,8 @@ def get_lib_from(search_directory, lib_extension='.so'):
2424
class LibtorrentRecipe(Recipe):
2525
# Todo: make recipe compatible with all p4a architectures
2626
'''
27-
.. note:: This recipe can be built only against API 21+ and arch armeabi-v7a
27+
.. note:: This recipe can be built only against API 21+ and an android
28+
ndk >= r19
2829
2930
.. versionchanged:: 0.6.0
3031
Rewrote recipe to support clang's build and boost 1.68. The following
@@ -33,9 +34,14 @@ class LibtorrentRecipe(Recipe):
3334
- Bumped version number to 1.2.0
3435
- added python 3 compatibility
3536
- new system to detect/copy generated libraries
37+
38+
.. versionchanged:: 2019.08.09.1.dev0
39+
40+
- Bumped version number to 1.2.1
41+
- Adapted to work with ndk-r19+
3642
'''
37-
version = '1_2_0'
38-
url = 'https://github.com/arvidn/libtorrent/archive/libtorrent_{version}.tar.gz'
43+
version = '1_2_1'
44+
url = 'https://github.com/arvidn/libtorrent/archive/libtorrent-{version}.tar.gz'
3945

4046
depends = ['boost']
4147
opt_depends = ['openssl']
@@ -76,7 +82,7 @@ def build_arch(self, arch):
7682
'-j' + str(cpu_count()),
7783
'--debug-configuration', # so we know if our python is detected
7884
# '--deprecated-functions=off',
79-
'toolset=clang-arm',
85+
'toolset=clang-{arch}'.format(arch=env['ARCH']),
8086
'abi=aapcs',
8187
'binary-format=elf',
8288
'cxxflags=-std=c++11',
@@ -105,8 +111,12 @@ def build_arch(self, arch):
105111
# Copy only the boost shared libraries into the libs folder. Because
106112
# boost build two boost_python libraries, we force to search the lib
107113
# into the corresponding build path.
108-
b2_build_dir = 'build/clang-linux-arm/release/{encryption}/' \
109-
'lt-visibility-hidden/'.format(encryption=crypto_folder)
114+
b2_build_dir = (
115+
'build/clang-linux-{arch}/release/{encryption}/'
116+
'lt-visibility-hidden/'.format(
117+
arch=env['ARCH'], encryption=crypto_folder
118+
)
119+
)
110120
boost_libs_dir = join(env['BOOST_BUILD_PATH'], 'bin.v2/libs')
111121
for boost_lib in listdir(boost_libs_dir):
112122
lib_path = get_lib_from(join(boost_libs_dir, boost_lib, b2_build_dir))

pythonforandroid/recipes/libtorrent/setup-lib-name.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
setup(
1616
- name='python-libtorrent',
1717
+ name='libtorrent',
18-
version='1.2.0',
18+
version='1.2.1',
1919
author='Arvid Norberg',
2020
author_email='[email protected]',

0 commit comments

Comments
 (0)