Reorganize native dep download and extraction (#154)
Summary: This moves the native setup to a separate gradle file and unpacks everything outside the build folder. That way we don't throw everything away on every incremental build. This is an intermediate step to get to a more declarative setup like Fresco has it and get rid of the individual hacks we have for every download. Pull Request resolved: https://github.com/facebook/Sonar/pull/154 Reviewed By: jknoxville Differential Revision: D8833812 Pulled By: passy fbshipit-source-id: 2424c9d6e22e6092c04af344e06939b4a6aba041
This commit is contained in:
committed by
Facebook Github Bot
parent
d34aba9e21
commit
cd6a5f9ff8
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,6 +7,8 @@ website/build
|
|||||||
build/
|
build/
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
|
||||||
|
android/third-party/external/
|
||||||
|
|
||||||
# Android / Intellij
|
# Android / Intellij
|
||||||
local.properties
|
local.properties
|
||||||
*.iml
|
*.iml
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ target_include_directories(${PACKAGE_NAME} PUBLIC "./")
|
|||||||
set(libjnihack_DIR ${CMAKE_SOURCE_DIR}/../libs/jni-hack/)
|
set(libjnihack_DIR ${CMAKE_SOURCE_DIR}/../libs/jni-hack/)
|
||||||
set(libfbjni_DIR ${CMAKE_SOURCE_DIR}/../libs/fbjni/)
|
set(libfbjni_DIR ${CMAKE_SOURCE_DIR}/../libs/fbjni/)
|
||||||
set(libsonar_DIR ${CMAKE_SOURCE_DIR}/../xplat/)
|
set(libsonar_DIR ${CMAKE_SOURCE_DIR}/../xplat/)
|
||||||
set(third_party_ndk ${PROJECT_SOURCE_DIR}/build/third-party-ndk)
|
set(external_DIR ${PROJECT_SOURCE_DIR}/third-party/external)
|
||||||
set(libfolly_DIR ${third_party_ndk}/folly/)
|
set(libfolly_DIR ${external_DIR}/folly/)
|
||||||
set(glog_DIR ${third_party_ndk}/glog)
|
set(glog_DIR ${external_DIR}/glog)
|
||||||
set(BOOST_DIR ${third_party_ndk}/boost/boost_1_63_0/)
|
set(BOOST_DIR ${external_DIR}/boost/boost_1_63_0/)
|
||||||
set(LIBEVENT_DIR ${third_party_ndk}/LibEvent/libevent-release-2.1.9/)
|
set(LIBEVENT_DIR ${external_DIR}/LibEvent/libevent-release-2.1.9/)
|
||||||
|
|
||||||
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
|
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
|
||||||
|
|
||||||
|
|||||||
@@ -1,204 +1,5 @@
|
|||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
apply plugin: 'de.undercouch.download'
|
|
||||||
|
|
||||||
import de.undercouch.gradle.tasks.download.Download
|
|
||||||
import org.apache.tools.ant.filters.ReplaceTokens
|
|
||||||
|
|
||||||
final def downloadsDir = new File("$buildDir/downloads")
|
|
||||||
final def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
|
|
||||||
|
|
||||||
task createNativeDepsDirectories {
|
|
||||||
downloadsDir.mkdirs()
|
|
||||||
thirdPartyNdkDir.mkdirs()
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
||||||
src 'https://github.com/google/glog/archive/v0.3.5.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'glog-0.3.5.tar.gz')
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareGlog(dependsOn: [downloadGlog], type: Copy) {
|
|
||||||
from tarTree(downloadGlog.dest)
|
|
||||||
from './third-party/glog/'
|
|
||||||
include 'glog-0.3.5/src/**/*', 'Android.mk', 'config.h', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
filesMatching('**/*.h.in') {
|
|
||||||
filter(ReplaceTokens, tokens: [
|
|
||||||
ac_cv_have_unistd_h: '1',
|
|
||||||
ac_cv_have_stdint_h: '1',
|
|
||||||
ac_cv_have_systypes_h: '1',
|
|
||||||
ac_cv_have_inttypes_h: '1',
|
|
||||||
ac_cv_have_libgflags: '0',
|
|
||||||
ac_google_start_namespace: 'namespace google {',
|
|
||||||
ac_cv_have_uint16_t: '1',
|
|
||||||
ac_cv_have_u_int16_t: '1',
|
|
||||||
ac_cv_have___uint16: '0',
|
|
||||||
ac_google_end_namespace: '}',
|
|
||||||
ac_cv_have___builtin_expect: '1',
|
|
||||||
ac_google_namespace: 'google',
|
|
||||||
ac_cv___attribute___noinline: '__attribute__ ((noinline))',
|
|
||||||
ac_cv___attribute___noreturn: '__attribute__ ((noreturn))',
|
|
||||||
ac_cv___attribute___printf_4_5: '__attribute__((__format__ (__printf__, 4, 5)))'
|
|
||||||
])
|
|
||||||
it.path = (it.name - '.in')
|
|
||||||
}
|
|
||||||
into "$thirdPartyNdkDir/glog"
|
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeGlog(dependsOn: [prepareGlog], type: Copy) {
|
|
||||||
from './third-party/glog/'
|
|
||||||
include 'logging.cc'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/glog/glog-0.3.5/src/"
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
||||||
src 'https://github.com/google/double-conversion/archive/v3.0.0.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'double-conversion-3.0.0.tar.gz')
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareDoubleConversion(dependsOn: [downloadDoubleConversion], type: Copy) {
|
|
||||||
from tarTree(downloadDoubleConversion.dest)
|
|
||||||
from './third-party/DoubleConversion/'
|
|
||||||
include 'double-conversion-3.0.0/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/double-conversion"
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
||||||
src 'https://github.com/react-native-community/boost-for-react-native/releases/download/v1.63.0-0/boost_1_63_0.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite true
|
|
||||||
dest new File(downloadsDir, 'boost_1_63_0.tar.gz')
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareBoost(dependsOn: [downloadBoost], type: Copy) {
|
|
||||||
from tarTree(resources.gzip(downloadBoost.dest))
|
|
||||||
include 'boost_1_63_0/boost/**/*.hpp', 'boost_1_63_0/boost/**/*.h', 'boost/boost/**/*.hpp', 'boost/boost/**/*.h'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/boost"
|
|
||||||
doLast {
|
|
||||||
file("$thirdPartyNdkDir/boost/boost").renameTo("$thirdPartyNdkDir/boost/boost_1_63_0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
||||||
src 'https://github.com/facebook/folly/archive/v2018.06.18.00.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'folly-2018.06.18.00.tar.gz');
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareFolly(dependsOn: [downloadFolly], type: Copy) {
|
|
||||||
from tarTree(downloadFolly.dest)
|
|
||||||
from './third-party/Folly/'
|
|
||||||
include 'folly-2018.06.18.00/folly/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
|
||||||
eachFile {fname -> fname.path = (fname.path - "folly-2018.06.18.00/")}
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/folly"
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Get rid off this hack.
|
|
||||||
task finalizeFolly(dependsOn: [prepareFolly], type: Copy) {
|
|
||||||
from './third-party/Folly/'
|
|
||||||
include 'AsyncServerSocket.cpp'
|
|
||||||
into "$thirdPartyNdkDir/folly/folly/io/async/"
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadLibEvent(dependsOn: [], type: Download) {
|
|
||||||
src 'https://github.com/priteshrnandgaonkar/libevent/archive/release-2.1.9.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'libevent-release-2.1.9.tar.gz');
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareLibEvent(dependsOn: [downloadLibEvent], type: Copy) {
|
|
||||||
from tarTree(downloadLibEvent.dest)
|
|
||||||
from './third-party/LibEvent/'
|
|
||||||
include 'libevent-release-2.1.9/**/*', 'build.gradle', 'ApplicationManifest.xml'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/LibEvent"
|
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeEvent(dependsOn: [prepareLibEvent], type: Copy) {
|
|
||||||
from './third-party/LibEvent/'
|
|
||||||
include 'event-config.h'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/LibEvent/libevent-release-2.1.9/include/event2/"
|
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeEvent2(dependsOn: [finalizeEvent], type: Copy) {
|
|
||||||
from './third-party/LibEvent/'
|
|
||||||
include 'libs/**/*'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/LibEvent/"
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadOpenSSLSource(dependsOn: [], type: Download) {
|
|
||||||
src 'https://www.openssl.org/source/openssl-1.1.0h.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'openssl-android-1.0.0.tar.gz');
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadOpenSSLLibs(dependsOn: [], type: Download) {
|
|
||||||
src 'https://github.com/passy/openssl-android/releases/download/1.1.0h-r2/openssl-1.1.0h-r2-prebuilt.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'openssl-1.1.0h-prebuilt.tar.gz');
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareOpenSSL(dependsOn: [downloadOpenSSLSource, downloadOpenSSLLibs], type: Copy) {
|
|
||||||
from tarTree(downloadOpenSSLSource.dest)
|
|
||||||
from tarTree(downloadOpenSSLLibs.dest)
|
|
||||||
from './third-party/OpenSSL/'
|
|
||||||
include 'openssl-1.1.0h/**/*'
|
|
||||||
include 'libs/**/*'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/OpenSSL/"
|
|
||||||
}
|
|
||||||
|
|
||||||
task configureOpenSSL(dependsOn: [prepareOpenSSL], type: Exec) {
|
|
||||||
workingDir "$thirdPartyNdkDir/OpenSSL/openssl-1.1.0h/"
|
|
||||||
// This is only to generate a buildconfig.h in the next step. I **believe**
|
|
||||||
// that the options here don't really matter for that file.
|
|
||||||
commandLine './Configure', 'dist'
|
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeOpenSSL(dependsOn: [configureOpenSSL], type: Exec) {
|
|
||||||
workingDir "$thirdPartyNdkDir/OpenSSL/openssl-1.1.0h/"
|
|
||||||
commandLine 'make', 'build_generated'
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadRSocket(dependsOn: [], type: Download) {
|
|
||||||
src 'https://github.com/priteshrnandgaonkar/rsocket-cpp/archive/0.10.1.tar.gz'
|
|
||||||
onlyIfNewer true
|
|
||||||
overwrite false
|
|
||||||
dest new File(downloadsDir, 'rsocket-cpp-0.10.1.tar.gz');
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareRSocket(dependsOn: [downloadRSocket], type: Copy) {
|
|
||||||
from tarTree(downloadRSocket.dest)
|
|
||||||
from './third-party/RSocket/'
|
|
||||||
include 'rsocket-cpp-0.10.1/**/*', 'build.gradle', 'ApplicationManifest.xml', 'CMakeLists.txt'
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into "$thirdPartyNdkDir/RSocket"
|
|
||||||
}
|
|
||||||
|
|
||||||
task prepareAllLibs() {
|
|
||||||
dependsOn finalizeGlog
|
|
||||||
dependsOn prepareDoubleConversion
|
|
||||||
dependsOn prepareBoost
|
|
||||||
dependsOn finalizeFolly
|
|
||||||
dependsOn finalizeEvent
|
|
||||||
dependsOn finalizeOpenSSL
|
|
||||||
dependsOn prepareRSocket
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.compileSdkVersion
|
compileSdkVersion rootProject.compileSdkVersion
|
||||||
@@ -215,17 +16,20 @@ android {
|
|||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments '-DANDROID_TOOLCHAIN=clang',
|
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_shared'
|
||||||
'-DANDROID_STL=c++_shared'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
manifest.srcFile './AndroidManifest.xml'
|
manifest {
|
||||||
|
srcFile './AndroidManifest.xml'
|
||||||
|
}
|
||||||
java {
|
java {
|
||||||
srcDir 'android'
|
srcDir 'android'
|
||||||
srcDir 'core'
|
srcDir 'core'
|
||||||
@@ -239,6 +43,7 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
path './CMakeLists.txt'
|
path './CMakeLists.txt'
|
||||||
@@ -248,6 +53,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly deps.lithoAnnotations
|
compileOnly deps.lithoAnnotations
|
||||||
implementation project(':fbjni')
|
implementation project(':fbjni')
|
||||||
|
implementation project(':third-party')
|
||||||
implementation deps.soloader
|
implementation deps.soloader
|
||||||
implementation deps.guava
|
implementation deps.guava
|
||||||
implementation deps.jsr305
|
implementation deps.jsr305
|
||||||
@@ -256,13 +62,11 @@ android {
|
|||||||
implementation deps.okhttp3
|
implementation deps.okhttp3
|
||||||
implementation deps.lithoCore
|
implementation deps.lithoCore
|
||||||
implementation deps.lithoWidget
|
implementation deps.lithoWidget
|
||||||
implementation 'org.mozilla:rhino:1.7.10'
|
implementation deps.rhino
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.afterEvaluate {
|
preBuild.dependsOn(tasks.getByPath(':third-party:prepare'))
|
||||||
preBuild.dependsOn prepareAllLibs
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: rootProject.file('gradle/release.gradle')
|
apply from: rootProject.file('gradle/release.gradle')
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion rootProject.minSdkVersion
|
minSdkVersion rootProject.minSdkVersion
|
||||||
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
||||||
applicationId "com.facebook.sonar.sample"
|
applicationId 'com.facebook.sonar.sample'
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
|
|||||||
@@ -4,32 +4,21 @@ package com.facebook.sonar.sample;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Network;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import com.facebook.sonar.plugins.sharedpreferences.SharedPreferencesSonarPlugin;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import android.widget.LinearLayout.LayoutParams;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import com.facebook.litho.sonar.LithoSonarDescriptors;
|
import com.facebook.litho.sonar.LithoSonarDescriptors;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import com.facebook.sonar.plugins.inspector.DescriptorMapping;
|
|
||||||
import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin;
|
|
||||||
import com.facebook.sonar.android.utils.SonarUtils;
|
|
||||||
import com.facebook.sonar.android.AndroidSonarClient;
|
import com.facebook.sonar.android.AndroidSonarClient;
|
||||||
import com.facebook.sonar.core.SonarClient;
|
import com.facebook.sonar.core.SonarClient;
|
||||||
import com.facebook.sonar.plugins.inspector.DescriptorMapping;
|
import com.facebook.sonar.plugins.inspector.DescriptorMapping;
|
||||||
import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin;
|
import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin;
|
||||||
import com.facebook.sonar.plugins.network.NetworkSonarPlugin;
|
import com.facebook.sonar.plugins.network.NetworkSonarPlugin;
|
||||||
import com.facebook.sonar.plugins.network.SonarOkhttpInterceptor;
|
import com.facebook.sonar.plugins.network.SonarOkhttpInterceptor;
|
||||||
import com.facebook.sonar.plugins.network.NetworkResponseFormatter;
|
import com.facebook.sonar.plugins.sharedpreferences.SharedPreferencesSonarPlugin;
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
public class SonarSampleApplication extends Application {
|
public class SonarSampleApplication extends Application {
|
||||||
|
|
||||||
static public OkHttpClient okhttpClient;
|
public static OkHttpClient okhttpClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
|||||||
3
android/third-party/AndroidManifest.xml
vendored
Normal file
3
android/third-party/AndroidManifest.xml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="com.facebook.sonar.thirdparty">
|
||||||
|
</manifest>
|
||||||
37
android/third-party/LibEvent/CMakeLists.txt
vendored
37
android/third-party/LibEvent/CMakeLists.txt
vendored
@@ -1,37 +0,0 @@
|
|||||||
cmake_minimum_required (VERSION 3.6.0)
|
|
||||||
|
|
||||||
PROJECT(libevent C)
|
|
||||||
enable_language(C)
|
|
||||||
set(PACKAGE_NAME libevent)
|
|
||||||
set(LIBEVENT_DIR libevent-release-2.1.8-stable)
|
|
||||||
list(APPEND DIR_LIST ${LIBEVENT_DIR}/)
|
|
||||||
list(APPEND DIR_LIST ${LIBEVENT_DIR}/include)
|
|
||||||
include_directories(${DIR_LIST})
|
|
||||||
list(APPEND SRCFILES ${LIBEVENT_DIR}/event.c
|
|
||||||
${LIBEVENT_DIR}/buffer.c
|
|
||||||
${LIBEVENT_DIR}/bufferevent.c
|
|
||||||
${LIBEVENT_DIR}/bufferevent_filter.c
|
|
||||||
${LIBEVENT_DIR}/bufferevent_ratelim.c
|
|
||||||
${LIBEVENT_DIR}/bufferevent_sock.c
|
|
||||||
${LIBEVENT_DIR}/epoll.c
|
|
||||||
${LIBEVENT_DIR}/epoll_sub.c
|
|
||||||
${LIBEVENT_DIR}/evdns.c
|
|
||||||
${LIBEVENT_DIR}/event_tagging.c
|
|
||||||
${LIBEVENT_DIR}/evmap.c
|
|
||||||
${LIBEVENT_DIR}/evrpc.c
|
|
||||||
${LIBEVENT_DIR}/evthread.c
|
|
||||||
${LIBEVENT_DIR}/evthread_pthread.c
|
|
||||||
${LIBEVENT_DIR}/evutil.c
|
|
||||||
${LIBEVENT_DIR}/evutil_rand.c
|
|
||||||
${LIBEVENT_DIR}/http.c
|
|
||||||
${LIBEVENT_DIR}/listener.c
|
|
||||||
${LIBEVENT_DIR}/log.c
|
|
||||||
${LIBEVENT_DIR}/poll.c
|
|
||||||
${LIBEVENT_DIR}/select.c
|
|
||||||
${LIBEVENT_DIR}/signal.c
|
|
||||||
${LIBEVENT_DIR}/strlcpy.c
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(${PACKAGE_NAME} SHARED ${SRCFILES})
|
|
||||||
install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/)
|
|
||||||
target_link_libraries(${PACKAGE_NAME})
|
|
||||||
24
android/third-party/build.gradle
vendored
Normal file
24
android/third-party/build.gradle
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply from: 'native.gradle'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion rootProject.compileSdkVersion
|
||||||
|
buildToolsVersion rootProject.buildToolsVersion
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion rootProject.minSdkVersion
|
||||||
|
targetSdkVersion rootProject.targetSdkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile './AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepare(dependsOn: [prepareAllLibs]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
build.dependsOn prepare
|
||||||
|
clean.dependsOn cleanNative
|
||||||
206
android/third-party/native.gradle
vendored
Normal file
206
android/third-party/native.gradle
vendored
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
|
final def downloadsDir = new File("$buildDir/downloads")
|
||||||
|
final def externalDir = new File("$projectDir/external")
|
||||||
|
|
||||||
|
final def getDownloadFileName = { final URL src ->
|
||||||
|
final def i = src.file.lastIndexOf('/')
|
||||||
|
return src.file.substring(i + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
task createNativeDepsDirectories {
|
||||||
|
downloadsDir.mkdirs()
|
||||||
|
externalDir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
task cleanNative(type: Delete) {
|
||||||
|
delete externalDir
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
|
||||||
|
src 'https://github.com/google/glog/archive/v0.3.5.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, 'glog-' + getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareGlog(dependsOn: [downloadGlog], type: Copy) {
|
||||||
|
from tarTree(downloadGlog.dest)
|
||||||
|
from './overrides/glog/'
|
||||||
|
include 'glog-0.3.5/src/**/*', 'Android.mk', 'config.h', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
filesMatching('**/*.h.in') {
|
||||||
|
filter(ReplaceTokens, tokens: [
|
||||||
|
ac_cv_have_unistd_h: '1',
|
||||||
|
ac_cv_have_stdint_h: '1',
|
||||||
|
ac_cv_have_systypes_h: '1',
|
||||||
|
ac_cv_have_inttypes_h: '1',
|
||||||
|
ac_cv_have_libgflags: '0',
|
||||||
|
ac_google_start_namespace: 'namespace google {',
|
||||||
|
ac_cv_have_uint16_t: '1',
|
||||||
|
ac_cv_have_u_int16_t: '1',
|
||||||
|
ac_cv_have___uint16: '0',
|
||||||
|
ac_google_end_namespace: '}',
|
||||||
|
ac_cv_have___builtin_expect: '1',
|
||||||
|
ac_google_namespace: 'google',
|
||||||
|
ac_cv___attribute___noinline: '__attribute__ ((noinline))',
|
||||||
|
ac_cv___attribute___noreturn: '__attribute__ ((noreturn))',
|
||||||
|
ac_cv___attribute___printf_4_5: '__attribute__((__format__ (__printf__, 4, 5)))'
|
||||||
|
])
|
||||||
|
it.path = (it.name - '.in')
|
||||||
|
}
|
||||||
|
into "$externalDir/glog"
|
||||||
|
}
|
||||||
|
|
||||||
|
task finalizeGlog(dependsOn: [prepareGlog], type: Copy) {
|
||||||
|
from './overrides/glog/'
|
||||||
|
include 'logging.cc'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/glog/glog-0.3.5/src/"
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
|
||||||
|
src 'https://github.com/google/double-conversion/archive/v3.0.0.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, 'double-conversion-' + getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareDoubleConversion(dependsOn: [downloadDoubleConversion], type: Copy) {
|
||||||
|
from tarTree(downloadDoubleConversion.dest)
|
||||||
|
from './overrides/DoubleConversion/'
|
||||||
|
include 'double-conversion-3.0.0/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/double-conversion"
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
|
||||||
|
src 'https://github.com/react-native-community/boost-for-react-native/releases/download/v1.63.0-0/boost_1_63_0.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite true
|
||||||
|
dest new File(downloadsDir, getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareBoost(dependsOn: [downloadBoost], type: Copy) {
|
||||||
|
from tarTree(resources.gzip(downloadBoost.dest))
|
||||||
|
include 'boost_1_63_0/boost/**/*.hpp', 'boost_1_63_0/boost/**/*.h', 'boost/boost/**/*.hpp', 'boost/boost/**/*.h'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/boost"
|
||||||
|
doLast {
|
||||||
|
file("$externalDir/boost/boost").renameTo("$externalDir/boost/boost_1_63_0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
|
||||||
|
src 'https://github.com/facebook/folly/archive/v2018.06.18.00.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, 'folly-' + getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareFolly(dependsOn: [downloadFolly], type: Copy) {
|
||||||
|
from tarTree(downloadFolly.dest)
|
||||||
|
from './overrides/Folly/'
|
||||||
|
include 'folly-2018.06.18.00/folly/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml'
|
||||||
|
eachFile { it.path = it.path - "folly-2018.06.18.00/" }
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/folly"
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Get rid off this hack.
|
||||||
|
task finalizeFolly(dependsOn: [prepareFolly], type: Copy) {
|
||||||
|
from './overrides/Folly/'
|
||||||
|
include 'AsyncServerSocket.cpp'
|
||||||
|
into "$externalDir/folly/folly/io/async/"
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadLibEvent(dependsOn: [], type: Download) {
|
||||||
|
src 'https://github.com/priteshrnandgaonkar/libevent/archive/release-2.1.9.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, 'libevent-' + getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareLibEvent(dependsOn: [downloadLibEvent], type: Copy) {
|
||||||
|
from tarTree(downloadLibEvent.dest)
|
||||||
|
from './overrides/LibEvent/'
|
||||||
|
include 'libevent-release-2.1.9/**/*', 'build.gradle', 'ApplicationManifest.xml'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/LibEvent"
|
||||||
|
}
|
||||||
|
|
||||||
|
task finalizeEvent(dependsOn: [prepareLibEvent], type: Copy) {
|
||||||
|
from './overrides/LibEvent/'
|
||||||
|
include 'event-config.h'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/LibEvent/libevent-release-2.1.9/include/event2/"
|
||||||
|
}
|
||||||
|
|
||||||
|
task finalizeEvent2(dependsOn: [finalizeEvent], type: Copy) {
|
||||||
|
from './overrides/LibEvent/'
|
||||||
|
include 'libs/**/*'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/LibEvent/"
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadOpenSSLSource(dependsOn: [], type: Download) {
|
||||||
|
src 'https://www.openssl.org/source/openssl-1.1.0h.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadOpenSSLLibs(dependsOn: [], type: Download) {
|
||||||
|
src 'https://github.com/passy/openssl-android/releases/download/1.1.0h-r2/openssl-1.1.0h-r2-prebuilt.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareOpenSSL(dependsOn: [downloadOpenSSLSource, downloadOpenSSLLibs], type: Copy) {
|
||||||
|
from tarTree(downloadOpenSSLSource.dest)
|
||||||
|
from tarTree(downloadOpenSSLLibs.dest)
|
||||||
|
from './overrides/OpenSSL/'
|
||||||
|
include 'openssl-1.1.0h/**/*'
|
||||||
|
include 'libs/**/*'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/OpenSSL/"
|
||||||
|
}
|
||||||
|
|
||||||
|
task configureOpenSSL(dependsOn: [prepareOpenSSL], type: Exec) {
|
||||||
|
workingDir "$externalDir/OpenSSL/openssl-1.1.0h/"
|
||||||
|
// This is only to generate a buildconfig.h in the next step. I **believe**
|
||||||
|
// that the options here don't really matter for that file.
|
||||||
|
commandLine './Configure', 'dist'
|
||||||
|
}
|
||||||
|
|
||||||
|
task finalizeOpenSSL(dependsOn: [configureOpenSSL], type: Exec) {
|
||||||
|
workingDir "$externalDir/OpenSSL/openssl-1.1.0h/"
|
||||||
|
commandLine 'make', 'build_generated'
|
||||||
|
onlyIf { !file("$externalDir/OpenSSL/openssl-1.1.0h/include/openssl/opensslconf.h").exists() }
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadRSocket(dependsOn: [], type: Download) {
|
||||||
|
src 'https://github.com/priteshrnandgaonkar/rsocket-cpp/archive/0.10.1.tar.gz'
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, 'rsocket-' + getDownloadFileName(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareRSocket(dependsOn: [downloadRSocket], type: Copy) {
|
||||||
|
from tarTree(downloadRSocket.dest)
|
||||||
|
from './overrides/RSocket/'
|
||||||
|
include 'rsocket-cpp-0.10.1/**/*', 'build.gradle', 'ApplicationManifest.xml', 'CMakeLists.txt'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
into "$externalDir/RSocket"
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareAllLibs() {
|
||||||
|
dependsOn finalizeGlog
|
||||||
|
dependsOn prepareDoubleConversion
|
||||||
|
dependsOn prepareBoost
|
||||||
|
dependsOn finalizeFolly
|
||||||
|
dependsOn finalizeEvent
|
||||||
|
dependsOn finalizeOpenSSL
|
||||||
|
dependsOn prepareRSocket
|
||||||
|
}
|
||||||
37
android/third-party/overrides/LibEvent/CMakeLists.txt
vendored
Normal file
37
android/third-party/overrides/LibEvent/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
cmake_minimum_required (VERSION 3.6.0)
|
||||||
|
|
||||||
|
PROJECT(libevent C)
|
||||||
|
enable_language(C)
|
||||||
|
set(PACKAGE_NAME libevent)
|
||||||
|
set(LIBEVENT_DIR libevent-release-2.1.8-stable)
|
||||||
|
list(APPEND DIR_LIST ${LIBEVENT_DIR}/)
|
||||||
|
list(APPEND DIR_LIST ${LIBEVENT_DIR}/include)
|
||||||
|
include_directories(${DIR_LIST})
|
||||||
|
list(APPEND SRCFILES ${LIBEVENT_DIR}/event.c
|
||||||
|
${LIBEVENT_DIR}/buffer.c
|
||||||
|
${LIBEVENT_DIR}/bufferevent.c
|
||||||
|
${LIBEVENT_DIR}/bufferevent_filter.c
|
||||||
|
${LIBEVENT_DIR}/bufferevent_ratelim.c
|
||||||
|
${LIBEVENT_DIR}/bufferevent_sock.c
|
||||||
|
${LIBEVENT_DIR}/epoll.c
|
||||||
|
${LIBEVENT_DIR}/epoll_sub.c
|
||||||
|
${LIBEVENT_DIR}/evdns.c
|
||||||
|
${LIBEVENT_DIR}/event_tagging.c
|
||||||
|
${LIBEVENT_DIR}/evmap.c
|
||||||
|
${LIBEVENT_DIR}/evrpc.c
|
||||||
|
${LIBEVENT_DIR}/evthread.c
|
||||||
|
${LIBEVENT_DIR}/evthread_pthread.c
|
||||||
|
${LIBEVENT_DIR}/evutil.c
|
||||||
|
${LIBEVENT_DIR}/evutil_rand.c
|
||||||
|
${LIBEVENT_DIR}/http.c
|
||||||
|
${LIBEVENT_DIR}/listener.c
|
||||||
|
${LIBEVENT_DIR}/log.c
|
||||||
|
${LIBEVENT_DIR}/poll.c
|
||||||
|
${LIBEVENT_DIR}/select.c
|
||||||
|
${LIBEVENT_DIR}/signal.c
|
||||||
|
${LIBEVENT_DIR}/strlcpy.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(${PACKAGE_NAME} SHARED ${SRCFILES})
|
||||||
|
install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/)
|
||||||
|
target_link_libraries(${PACKAGE_NAME})
|
||||||
@@ -9,10 +9,13 @@ buildscript {
|
|||||||
classpath "com.github.dcendents:android-maven-gradle-plugin:${ANDROID_MAVEN_GRADLE_PLUGIN_VERSION}"
|
classpath "com.github.dcendents:android-maven-gradle-plugin:${ANDROID_MAVEN_GRADLE_PLUGIN_VERSION}"
|
||||||
classpath "com.github.ben-manes:gradle-versions-plugin:${GRADLE_VERSIONS_PLUGIN_VERSION}"
|
classpath "com.github.ben-manes:gradle-versions-plugin:${GRADLE_VERSIONS_PLUGIN_VERSION}"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN_VERSION}"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN_VERSION}"
|
||||||
classpath 'de.undercouch:gradle-download-task:3.1.2'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'de.undercouch.download' version '3.4.3'
|
||||||
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
|||||||
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
|||||||
|
#Thu Jul 12 10:47:54 BST 2018
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
|
||||||
|
|||||||
@@ -17,14 +17,16 @@ include ':doubleconversion'
|
|||||||
include ':glog'
|
include ':glog'
|
||||||
include ':libevent'
|
include ':libevent'
|
||||||
include ':rsocket'
|
include ':rsocket'
|
||||||
|
include ':third-party'
|
||||||
|
|
||||||
project(':fbjni').projectDir = file('libs/fbjni')
|
project(':fbjni').projectDir = file('libs/fbjni')
|
||||||
project(':easywsclient').projectDir = file('libs/easywsclient')
|
project(':easywsclient').projectDir = file('libs/easywsclient')
|
||||||
project(':sonarcpp').projectDir = file('xplat')
|
project(':sonarcpp').projectDir = file('xplat')
|
||||||
project(':sample').projectDir = file('android/sample')
|
project(':sample').projectDir = file('android/sample')
|
||||||
project(':android').projectDir = file('android')
|
project(':android').projectDir = file('android')
|
||||||
project(':doubleconversion').projectDir = file('android/build/third-party-ndk/double-conversion/')
|
project(':doubleconversion').projectDir = file('android/third-party/external/double-conversion/')
|
||||||
project(':glog').projectDir = file('android/build/third-party-ndk/glog/')
|
project(':glog').projectDir = file('android/third-party/external/glog/')
|
||||||
project(':folly').projectDir = file('android/build/third-party-ndk/folly/')
|
project(':folly').projectDir = file('android/third-party/external/folly/')
|
||||||
project(':libevent').projectDir = file('android/build/third-party-ndk/LibEvent/')
|
project(':libevent').projectDir = file('android/third-party/external/LibEvent/')
|
||||||
project(':rsocket').projectDir = file('android/build/third-party-ndk/RSocket')
|
project(':rsocket').projectDir = file('android/third-party/external/RSocket/')
|
||||||
|
project(':third-party').projectDir = file('android/third-party/')
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ set(PACKAGE_NAME sonarcpp)
|
|||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
set(third_party_ndk ${PROJECT_SOURCE_DIR}/../android/build/third-party-ndk)
|
set(external_DIR ${PROJECT_SOURCE_DIR}/../android/third-party/external)
|
||||||
set(libfolly_DIR ${third_party_ndk}/folly/)
|
set(libfolly_DIR ${external_DIR}/folly/)
|
||||||
set(rsocket_DIR ${third_party_ndk}/RSocket/)
|
set(rsocket_DIR ${external_DIR}/RSocket/)
|
||||||
set(easywsclient_DIR ../libs/)
|
set(easywsclient_DIR ../libs/)
|
||||||
set(glog_DIR ${third_party_ndk}/glog)
|
set(glog_DIR ${external_DIR}/glog)
|
||||||
set(BOOST_DIR ${third_party_ndk}/boost/boost_1_63_0/)
|
set(BOOST_DIR ${external_DIR}/boost/boost_1_63_0/)
|
||||||
set(LIBEVENT_DIR ${third_party_ndk}/LibEvent/libevent-release-2.1.9/)
|
set(LIBEVENT_DIR ${external_DIR}/LibEvent/libevent-release-2.1.9/)
|
||||||
set(DOUBLECONVERSION_DIR ${third_party_ndk}/double-conversion/double-conversion-3.0.0/)
|
set(DOUBLECONVERSION_DIR ${external_DIR}/double-conversion/double-conversion-3.0.0/)
|
||||||
set(OPENSSL_DIR ${third_party_ndk}/OpenSSL/openssl-1.1.0h/)
|
set(OPENSSL_DIR ${external_DIR}/OpenSSL/openssl-1.1.0h/)
|
||||||
|
|
||||||
list(APPEND dir_list ./)
|
list(APPEND dir_list ./)
|
||||||
list(APPEND dir_list ./Sonar)
|
list(APPEND dir_list ./Sonar)
|
||||||
@@ -67,7 +67,7 @@ target_include_directories(${PACKAGE_NAME} PRIVATE
|
|||||||
${glog_DIR}/glog-0.3.5/src/
|
${glog_DIR}/glog-0.3.5/src/
|
||||||
)
|
)
|
||||||
|
|
||||||
set(OPENSSL_LINK_DIRECTORIES ${third_party_ndk}/OpenSSL/libs/${ANDROID_ABI}/)
|
set(OPENSSL_LINK_DIRECTORIES ${external_DIR}/OpenSSL/libs/${ANDROID_ABI}/)
|
||||||
find_path(OPENSSL_LIBRARY libssl.a HINTS ${OPENSSL_LINK_DIRECTORIES})
|
find_path(OPENSSL_LIBRARY libssl.a HINTS ${OPENSSL_LINK_DIRECTORIES})
|
||||||
|
|
||||||
target_link_libraries(${PACKAGE_NAME} folly rsocket glog double-conversion log event ${OPENSSL_LINK_DIRECTORIES}/libssl.a ${OPENSSL_LINK_DIRECTORIES}/libcrypto.a)
|
target_link_libraries(${PACKAGE_NAME} folly rsocket glog double-conversion log event ${OPENSSL_LINK_DIRECTORIES}/libssl.a ${OPENSSL_LINK_DIRECTORIES}/libcrypto.a)
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation project(':third-party')
|
||||||
implementation project(':rsocket')
|
implementation project(':rsocket')
|
||||||
implementation project(':folly')
|
implementation project(':folly')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preBuild.dependsOn(tasks.getByPath(':third-party:prepare'))
|
||||||
|
|||||||
Reference in New Issue
Block a user