refactor makefile

This commit is contained in:
Konstantin Käfer
2015-01-29 18:30:46 +01:00
parent 3d51e116a8
commit 29baacf3a5
68 changed files with 1317 additions and 690 deletions

161
Makefile
View File

@@ -1,106 +1,161 @@
BUILDTYPE ?= Release
PYTHON ?= python
V ?= 1
PREFIX ?= /usr/local
JOBS ?= 1
ifeq ($(shell uname -s), Darwin)
PLATFORM ?= osx
DEFAULT_HOST ?= osx
endif
PLATFORM ?= linux
DEFAULT_HOST ?= linux
.PHONY: all
all: mbgl
#### Dependencies ##############################################################
config.gypi: configure
./configure
config-ios.gypi: configure
MASON_PLATFORM=ios ./configure config-ios.gypi
config-android.gypi: configure __android__/configure
__android__/configure:
$(ENV) ./configure config-android.gypi
#### Configuration defaults ####################################################
__osx__/%: HOST ?= osx
__osx__/%: HEADLESS ?= cgl
__osx__/%: PLATFORM ?= osx
__osx__/%: ASSET ?= fs
__osx__/%: HTTP ?= nsurl
__osx__/%: CACHE ?= sqlite
__ios__/%: HOST = ios
__ios__/%: HEADLESS ?= none
__ios__/%: PLATFORM ?= ios
__ios__/%: ASSET ?= fs
__ios__/%: HTTP ?= nsurl
__ios__/%: CACHE ?= sqlite
__linux__/%: HOST = linux
__linux__/%: HEADLESS ?= glx
__linux__/%: PLATFORM ?= linux
__linux__/%: ASSET ?= fs
__linux__/%: HTTP ?= curl
__linux__/%: CACHE ?= sqlite
__android__/%: ENV=$(shell ./scripts/android_env.sh)
__android__/%: HOST = android
__android__/%: HEADLESS ?= none
__android__/%: PLATFORM ?= android
__android__/%: ASSET ?= zip
__android__/%: HTTP ?= curl
__android__/%: CACHE ?= sqlite
CONFIG_STRING += -Dhost=$(HOST)
CONFIG_STRING += -Dheadless_lib=$(HEADLESS)
CONFIG_STRING += -Dplatform_lib=$(PLATFORM)
CONFIG_STRING += -Dasset_lib=$(ASSET)
CONFIG_STRING += -Dhttp_lib=$(HTTP)
CONFIG_STRING += -Dcache_lib=$(CACHE)
CONFIG_STRING += --depth=.
CONFIG_STRING += -Goutput_dir=..
#### Library builds ############################################################
.PHONY: mbgl
mbgl: build/mbgl/Makefile
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-core mbgl-$(PLATFORM) mbgl-headless
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) everything
.PHONY: install
install: build/mbgl/Makefile
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) install
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) install
.PHONY: standalone
standalone: build/mbgl/Makefile
LINK=`pwd`/gyp/link.py $(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) standalone
LINK=`pwd`/gyp/link.py $(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) standalone
#### Build scripts #############################################################
#### Application buidls ########################################################
.PHONY: build/mbgl/Makefile
build/mbgl/Makefile: mbgl.gyp config.gypi
deps/run_gyp mbgl.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build/mbgl -f make
build/mbgl/Makefile: mbgl.gyp config.gypi __$(DEFAULT_HOST)__/mbgl
__%__/mbgl:
deps/run_gyp mbgl.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build/mbgl -f make
.PHONY: build/test/Makefile
build/test/Makefile: test/test.gyp config.gypi
deps/run_gyp test/test.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build/test -f make
build/test/Makefile: test/test.gyp config.gypi __$(DEFAULT_HOST)__/test
__%__/test:
deps/run_gyp test/test.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build/test -f make
.PHONY: build/linux/Makefile
build/linux/Makefile: linux/mapboxgl-app.gyp config.gypi
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=linux --depth=. -Goutput_dir=.. --generator-output=./build/linux -f make
build/linux/Makefile: linux/mapboxgl-app.gyp config.gypi __linux__/linux
__linux__/linux:
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build/linux -f make
.PHONY: build/macosx/Makefile
build/macosx/Makefile: macosx/mapboxgl-app.gyp config.gypi
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=osx --depth=. -Goutput_dir=.. --generator-output=./build/macosx -f make
build/macosx/Makefile: macosx/mapboxgl-app.gyp config.gypi __osx__/osx
__osx__/osx:
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build/macosx -f make
.PHONY: build/render/Makefile
build/render/Makefile: bin/render.gyp config.gypi
deps/run_gyp bin/render.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build/render -f make
build/render/Makefile: bin/render.gyp config.gypi __$(DEFAULT_HOST)__/render
__%__/render:
deps/run_gyp bin/render.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build/render -f make
.PHONY: build/test/test.xcodeproj
build/test/test.xcodeproj: test/test.gyp config.gypi
deps/run_gyp test/test.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build -f xcode
build/test/test.xcodeproj: test/test.gyp config.gypi __osx__/test-xcode
__osx__/test-xcode:
deps/run_gyp test/test.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build -f xcode
.PHONY: build/macosx/mapboxgl-app.xcodeproj
build/macosx/mapboxgl-app.xcodeproj: macosx/mapboxgl-app.gyp config.gypi
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=osx --depth=. --generator-output=./build -f xcode
build/macosx/mapboxgl-app.xcodeproj: macosx/mapboxgl-app.gyp config.gypi __osx__/app-xcode
__osx__/app-xcode:
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build -f xcode
.PHONY: build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj
build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj: ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp config-ios.gypi
deps/run_gyp ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp -Iconfig-ios.gypi -Dplatform=ios --depth=. --generator-output=./build -f xcode
build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj: ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp config-ios.gypi __ios__/app-xcode
__ios__/app-xcode:
deps/run_gyp ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp -Iconfig-ios.gypi $(CONFIG_STRING) --generator-output=./build -f xcode
.PHONY: build/linux/mapboxgl-app.xcodeproj
build/linux/mapboxgl-app.xcodeproj: linux/mapboxgl-app.gyp config.gypi
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=linux --depth=. --generator-output=./build -f xcode
build/linux/mapboxgl-app.xcodeproj: linux/mapboxgl-app.gyp config.gypi __linux__/app-xcode
__linux__/app-xcode:
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build -f xcode
.PHONY: build/bin/render.xcodeproj
build/bin/render.xcodeproj: bin/render.gyp config.gypi
deps/run_gyp bin/render.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. --generator-output=./build -f xcode
build/bin/render.xcodeproj: bin/render.gyp config.gypi __$(HOST)__/render-xcode
__%__/render-xcode:
deps/run_gyp bin/render.gyp -Iconfig.gypi $(CONFIG_STRING) --generator-output=./build -f xcode
.PHONY: build/android/Makefile
build/android/Makefile: android/mapboxgl-app.gyp config.gypi __android__/android-make
__android__/android-make:
@echo deps/run_gyp android/mapboxgl-app.gyp -Iconfig-android.gypi $(CONFIG_STRING) --generator-output=./build/android -f make-android
@$(ENV) deps/run_gyp android/mapboxgl-app.gyp -Iconfig-android.gypi $(CONFIG_STRING) --generator-output=./build/android -f make-android
.PHONY: android
android:
./scripts/local_mason.sh && \
MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./.mason/mason env PATH && \
export CXX="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CXX`" && \
export CC="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CC`" && \
export LD="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env LD`" && \
export LINK="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CXX`" && \
export AR="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env AR`" && \
export RANLIB="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env RANLIB`" && \
export STRIP="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env STRIP`" && \
export LDFLAGS="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env LDFLAGS` ${LDFLAGS}" && \
export CFLAGS="`MASON_DIR=./.mason MASON_PLATFORM= MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CFLAGS` ${CFLAGS}" && \
export CPPFLAGS="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CPPFLAGS` ${CPPFLAGS}" && \
export PATH="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env PATH`:${PATH}" && \
export JNIDIR="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env JNIDIR`" && \
MASON_PLATFORM=android MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./configure config-android.gypi && \
deps/run_gyp android/mapboxgl-app.gyp -Iconfig-android.gypi -Dplatform=android --depth=. --generator-output=./build/android/$(MASON_ANDROID_ABI) -f make-android && \
$(MAKE) -C build/android/$(MASON_ANDROID_ABI) -j$(JOBS) BUILDTYPE=$(BUILDTYPE) V=$(V) androidapp && \
BUILDTYPE=$(BUILDTYPE) MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./android/scripts/copy-files.sh && \
cd android/java && \
./gradlew --parallel-threads=$(JOBS) build
android: __android__/android
__android__/android: build/android/Makefile
@echo $(MAKE) -C build/android BUILDTYPE=$(BUILDTYPE) androidapp
@$(ENV) $(MAKE) -C build/android BUILDTYPE=$(BUILDTYPE) androidapp
mkdir -p android/java/lib/src/main/jniLibs/armeabi-v7a
cp build/$(BUILDTYPE)/lib.target/libmapbox-gl.so android/java/lib/src/main/jniLibs/armeabi-v7a/libmapbox-gl.so
mkdir -p android/java/lib/src/main/assets
cp build/$(BUILDTYPE)/ca-bundle.crt android/java/lib/src/main/assets/ca-bundle.crt
cp -r build/$(BUILDTYPE)/styles android/java/lib/src/main/assets/styles
cd android/java && ./gradlew --parallel-threads=$(JOBS) build
##### Test cases ###############################################################
test: build/test/Makefile
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) test
test-%: test
./scripts/run_tests.sh --gtest_filter=$*
@@ -109,12 +164,12 @@ test-%: test
xtest: build/test/test.xcodeproj
open ./build/test/test.xcodeproj
##### Makefile builds ##########################################################
##### Makefile builds ##########################################################
# Builds the linux app with make.
linux: build/linux/Makefile
$(MAKE) -C build/linux BUILDTYPE=$(BUILDTYPE) V=$(V) linuxapp
$(MAKE) -C build/linux BUILDTYPE=$(BUILDTYPE) linuxapp
# Executes the Linux binary
run-linux: linux
@@ -122,7 +177,7 @@ run-linux: linux
# Builds the OS X app with make.
osx: build/macosx/Makefile
$(MAKE) -C build/macosx BUILDTYPE=$(BUILDTYPE) V=$(V) osxapp
$(MAKE) -C build/macosx BUILDTYPE=$(BUILDTYPE) osxapp
# Executes the OS X binary
run-osx: osx
@@ -130,7 +185,7 @@ run-osx: osx
# Builds the CLI render app
render: build/render/Makefile
$(MAKE) -C build/render BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-render
$(MAKE) -C build/render BUILDTYPE=$(BUILDTYPE) mbgl-render
##### Xcode projects ###########################################################

View File

@@ -18,6 +18,7 @@
#include <mbgl/platform/android/log_android.hpp>
#include <mbgl/platform/event.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/storage/network_status.hpp>
#pragma clang diagnostic ignored "-Wunused-parameter"
@@ -423,14 +424,14 @@ nativeSetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring a
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetAccessToken");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken));
nativeMapView->getMap().setAccessToken(std_string_from_jstring(env, accessToken));
}
jstring JNICALL nativeGetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAccessToken");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken());
return std_string_to_jstring(env, nativeMapView->getMap().getAccessToken());
}
void JNICALL nativeCancelTransitions(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
@@ -701,8 +702,9 @@ void JNICALL
nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean status) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetReachability");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getFileSource().setReachability(status);
if (status) {
mbgl::NetworkStatus::Reachable();
}
}
}

View File

@@ -52,14 +52,10 @@ void log_gl_string(GLenum name, const char *label) {
}
}
// Returns the path to the default cache database on this system.
std::string defaultCacheDatabase() {
return mbgl::android::cachePath + "/mbgl-cache.db";
}
NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
: mbgl::View(*this),
fileSource(defaultCacheDatabase()),
fileCache(mbgl::android::cachePath + "/mbgl-cache.db"),
fileSource(&fileCache),
map(*this, fileSource) {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
@@ -145,7 +141,7 @@ void NativeMapView::notify() {
mbgl::Map &NativeMapView::getMap() { return map; }
mbgl::CachingHTTPFileSource &NativeMapView::getFileSource() { return fileSource; }
mbgl::DefaultFileSource &NativeMapView::getFileSource() { return fileSource; }
bool NativeMapView::inEmulator() {
// Detect if we are in emulator

View File

@@ -3,14 +3,24 @@
'../gyp/common.gypi',
],
'targets': [
{
'target_name': 'androidapp',
{ 'target_name': 'androidapp',
'product_name': 'mapbox-gl',
'type': 'shared_library',
'dependencies': [
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
'../mbgl.gyp:copy_certificate_bundle',
],
'sources': [
'./cpp/native_map_view.cpp',
'./cpp/jni.cpp',
],
'cflags_cc': [
'-I<(boost_root)/include',
],
@@ -50,11 +60,6 @@
'libraries': [ '<@(ldflags)' ],
}]
],
'dependencies': [
'../mapboxgl.gyp:mbgl-standalone',
'../mapboxgl.gyp:mbgl-android',
'../mapboxgl.gyp:copy_certificate_bundle',
],
'copies': [{
'files': [ '../styles' ],
'destination': '<(PRODUCT_DIR)'

View File

@@ -9,7 +9,8 @@
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/storage/caching_http_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
#if __APPLE__
#include <mbgl/platform/darwin/log_nslog.hpp>
@@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
int height = 256;
double pixelRatio = 1.0;
std::string output = "out.png";
std::string cache = "cache.sqlite";
std::string cache_file = "cache.sqlite";
std::vector<std::string> classes;
std::string token;
@@ -51,7 +52,7 @@ int main(int argc, char *argv[]) {
("class,c", po::value(&classes)->value_name("name"), "Class name")
("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token")
("output,o", po::value(&output)->value_name("file")->default_value(output), "Output file name")
("cache,d", po::value(&cache)->value_name("file")->default_value(cache), "Cache database file name")
("cache,d", po::value(&cache_file)->value_name("file")->default_value(cache_file), "Cache database file name")
;
try {
@@ -74,7 +75,8 @@ int main(int argc, char *argv[]) {
Log::Set<StderrLogBackend>();
#endif
CachingHTTPFileSource fileSource(cache);
mbgl::SQLiteCache cache(cache_file);
mbgl::DefaultFileSource fileSource(&cache);
// Try to load the token from the environment.
if (!token.size()) {
@@ -84,14 +86,15 @@ int main(int argc, char *argv[]) {
}
}
// Set access token if present
if (token.size()) {
fileSource.setAccessToken(std::string(token));
}
HeadlessView view;
Map map(view, fileSource);
// Set access token if present
if (token.size()) {
map.setAccessToken(std::string(token));
}
map.setStyleJSON(style, ".");
map.setClasses(classes);

View File

@@ -3,51 +3,54 @@
'../gyp/common.gypi',
],
'targets': [
{
'target_name': 'mbgl-render',
{ 'target_name': 'mbgl-render',
'product_name': 'mbgl-render',
'type': 'executable',
'dependencies': [
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:headless-<(headless_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
'../mbgl.gyp:copy_certificate_bundle',
],
'include_dirs': [
'../src',
],
'sources': [
'./render.cpp',
],
'variables' : {
'cflags': [
'<@(uv_cflags)',
'<@(png_cflags)',
'cflags_cc': [
'<@(glfw3_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(glfw3_ldflags)',
'<@(uv_ldflags)',
'<@(sqlite3_static_libs)',
'<@(sqlite3_ldflags)',
'<@(curl_ldflags)',
'<@(png_ldflags)',
'<@(uv_static_libs)',
'-L<(boost_root)/lib',
'-lboost_program_options'
],
'libraries': [
'<@(glfw3_static_libs)',
],
},
'conditions': [
# add libuv include path and OpenGL libs
['OS == "mac"',
{
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': ['<@(cflags)'],
'OTHER_LDFLAGS': ['<@(ldflags)'],
},
},
{
'cflags': ['<@(cflags)'],
'libraries': ['<@(ldflags)'],
}],
],
'include_dirs': [ '../src' ],
'dependencies': [
'../mbgl.gyp:<(core_library)',
'../mbgl.gyp:<(headless_library)',
'../mbgl.gyp:<(platform_library)',
'../mbgl.gyp:copy_certificate_bundle',
['OS == "mac"', {
'libraries': [ '<@(libraries)' ],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
}
}, {
'cflags_cc': [ '<@(cflags_cc)' ],
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
}]
],
},
],

1
configure vendored
View File

@@ -46,6 +46,7 @@ case ${MASON_PLATFORM} in
ZLIB_VERSION=system
BOOST_VERSION=system
NUNICODE_VERSION=1.5.1
LIBZIP_VERSION=0.11.2
;;
esac

52
gyp/asset-fs.gypi Normal file
View File

@@ -0,0 +1,52 @@
{
'targets': [
{ 'target_name': 'asset-fs',
'product_name': 'mbgl-asset-fs',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/default/asset_request_fs.cpp',
],
'include_dirs': [
'../include',
],
'variables': {
'cflags_cc': [
'<@(uv_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(uv_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
],
},
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
},
}, {
'cflags_cc': [ '<@(cflags_cc)' ],
}],
],
'link_settings': {
'conditions': [
['OS == "mac"', {
'libraries': [ '<@(libraries)' ],
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
}, {
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
}]
],
},
},
],
}

62
gyp/asset-zip.gypi Normal file
View File

@@ -0,0 +1,62 @@
{
'targets': [
{ 'target_name': 'asset-zip',
'product_name': 'mbgl-asset-zip',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/default/asset_request_zip.cpp',
'../platform/default/uv_zip.c',
],
'include_dirs': [
'../include',
],
'variables': {
'cflags': [
'<@(uv_cflags)',
'<@(zip_cflags)',
],
'cflags_cc': [
'<@(uv_cflags)',
'<@(zip_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(uv_ldflags)',
'<@(zip_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
'<@(zip_static_libs)',
],
},
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_CFLAGS': [ '<@(cflags)' ],
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
},
}, {
'cflags': [ '<@(cflags)' ],
'cflags_cc': [ '<@(cflags_cc)' ],
}],
],
'link_settings': {
'conditions': [
['OS == "mac"', {
'libraries': [ '<@(libraries)' ],
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
}, {
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
}]
],
},
},
],
}

View File

@@ -1,16 +1,13 @@
{
'targets': [
{ 'target_name': 'mbgl-storage-curl',
'product_name': 'mbgl-storage-curl',
{ 'target_name': 'cache-sqlite',
'product_name': 'mbgl-cache-sqlite',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/default/default_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/default/http_request_curl.cpp',
'../platform/default/asset_request_libuv.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
'../platform/default/compression.hpp',
@@ -25,19 +22,15 @@
'cflags_cc': [
'<@(uv_cflags)',
'<@(sqlite3_cflags)',
'<@(curl_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(uv_ldflags)',
'<@(sqlite3_ldflags)',
'<@(curl_ldflags)',
'<@(zlib_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
'<@(sqlite3_static_libs)',
'<@(curl_static_libs)',
'<@(zlib_static_libs)',
],
},

View File

@@ -1,7 +1,4 @@
{
'includes': [
'./variables.gypi',
],
'variables': {
'install_prefix%': '',
'standalone_product_dir':'<!@(pwd)/build',
@@ -60,7 +57,7 @@
}, {
'cflags_cc': [ '-fPIC' ],
}],
['platform == "ios"', {
['host == "ios"', {
'xcode_settings': {
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',

View File

@@ -1,6 +1,6 @@
{
'targets': [
{ 'target_name': 'mbgl-core',
{ 'target_name': 'core',
'product_name': 'mbgl-core',
'type': 'static_library',
'standalone_static_library': 1,

View File

@@ -1,7 +1,7 @@
{
'targets': [
{ 'target_name': 'mbgl-headless',
'product_name': 'mbgl-headless',
{ 'target_name': 'headless-cgl',
'product_name': 'mbgl-headless-cgl',
'type': 'static_library',
'standalone_static_library': 1,

18
gyp/headless-glx.gypi Normal file
View File

@@ -0,0 +1,18 @@
{
'targets': [
{ 'target_name': 'headless-glx',
'product_name': 'mbgl-headless-glx',
'type': 'static_library',
'standalone_static_library': 1,
'sources': [
'../platform/default/headless_view.cpp',
'../platform/default/headless_display.cpp',
],
'include_dirs': [
'../include',
],
},
],
}

55
gyp/http-curl.gypi Normal file
View File

@@ -0,0 +1,55 @@
{
'targets': [
{ 'target_name': 'http-curl',
'product_name': 'mbgl-http-curl',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/default/http_request_curl.cpp',
],
'include_dirs': [
'../include',
],
'variables': {
'cflags_cc': [
'<@(uv_cflags)',
'<@(curl_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(uv_ldflags)',
'<@(curl_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
'<@(curl_static_libs)',
],
},
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
},
}, {
'cflags_cc': [ '<@(cflags_cc)' ],
}],
],
'link_settings': {
'conditions': [
['OS == "mac"', {
'libraries': [ '<@(libraries)' ],
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
}, {
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
}]
],
},
},
],
}

43
gyp/http-nsurl.gypi Normal file
View File

@@ -0,0 +1,43 @@
{
'targets': [
{ 'target_name': 'http-nsurl',
'product_name': 'mbgl-http-nsurl',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/darwin/http_request_nsurl.mm',
],
'include_dirs': [
'../include',
],
'variables': {
'cflags_cc': [
'<@(uv_cflags)',
],
'ldflags': [
'-framework Foundation', # For NSURLRequest
'<@(uv_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
],
},
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
'CLANG_ENABLE_OBJC_ARC': 'NO',
},
'link_settings': {
'libraries': [ '<@(libraries)' ],
'xcode_settings': {
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
},
},
},
],
}

View File

@@ -6,18 +6,22 @@
'type': 'none',
'hard_dependency': 1,
'dependencies': [
'<(core_library)',
'<(headless_library)',
'<(platform_library)',
'<(storage_library)',
'core',
'<(headless_lib)',
'<(platform_lib)',
'<(http_lib)',
'<(asset_lib)',
'<(cache_lib)',
'mbgl-standalone',
],
'copies': [
{ 'files': [ '<(standalone_product_dir)/libmbgl.a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/libmbgl-core.a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/libmbgl-headless.a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(platform_library).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(storage_library).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(headless_lib).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(platform_lib).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(http_lib).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(asset_lib).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '<(PRODUCT_DIR)/lib<(cache_lib).a' ], 'destination': '<(install_prefix)/lib' },
{ 'files': [ '../include/mbgl' ], 'destination': '<(install_prefix)/include' },
],
'variables': {
@@ -36,7 +40,7 @@
],
},
'actions': [
{ 'action_name': 'mbgl-config',
{ 'action_name': 'mbgl-config',
'inputs': [
'../utils/mbgl-config/mbgl-config.template.sh',
'../utils/mbgl-config/build.sh',
@@ -47,7 +51,6 @@
'action': [
'./utils/mbgl-config/build.sh',
'<(install_prefix)',
'<(platform)',
'<@(sqlite3_static_libs)',
'<@(sqlite3_ldflags)',
'<@(curl_ldflags)',

6
gyp/load.gypi Normal file
View File

@@ -0,0 +1,6 @@
{
'conditions': [
['platform_library == "mbglosx"', {
}],
],
}

View File

@@ -1,16 +0,0 @@
{
'targets': [
{ 'target_name': 'standalone',
'product_name': 'libmbgl.a',
'type': 'executable',
'hard_dependency': 1,
'dependencies': [
'<(core_library)',
'<(platform_library)',
'<(storage_library)',
'<(headless_library)',
],
},
],
}

View File

@@ -1,62 +0,0 @@
{
'targets': [
{ 'target_name': 'mbgl-storage-cocoa',
'product_name': 'mbgl-storage-cocoa',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'sources': [
'../platform/default/default_file_source.cpp',
'../platform/default/sqlite_cache.cpp',
'../platform/darwin/http_request_cocoa.mm',
'../platform/default/asset_request_libuv.cpp',
'../platform/default/sqlite3.hpp',
'../platform/default/sqlite3.cpp',
'../platform/default/compression.hpp',
'../platform/default/compression.cpp',
],
'include_dirs': [
'../include',
],
'variables': {
'cflags_cc': [
'<@(uv_cflags)',
'<@(sqlite3_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'-framework Foundation', # For NSURLRequest
'<@(uv_ldflags)',
'<@(sqlite3_ldflags)',
'<@(zlib_ldflags)',
],
'libraries': [
'<@(uv_static_libs)',
'<@(sqlite3_static_libs)',
'<@(zlib_static_libs)',
],
},
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
'CLANG_ENABLE_OBJC_ARC': 'NO',
},
'link_settings': {
'libraries': [ '<@(libraries)' ],
'xcode_settings': {
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
},
},
'direct_dependent_settings': {
'include_dirs': [
'../include',
],
},
},
],
}

20
gyp/none.gypi Normal file
View File

@@ -0,0 +1,20 @@
{
'targets': [
{ 'target_name': 'http-none',
'product_name': 'mbgl-http-none',
'type': 'none',
},
{ 'target_name': 'asset-none',
'product_name': 'mbgl-asset-none',
'type': 'none',
},
{ 'target_name': 'cache-none',
'product_name': 'mbgl-cache-none',
'type': 'none',
},
{ 'target_name': 'headless-none',
'product_name': 'mbgl-headless-none',
'type': 'none',
},
],
}

View File

@@ -1,82 +1,75 @@
{
'targets': [
{ 'target_name': 'mbgl-android',
'product_name': 'mbgl-android',
{ 'target_name': 'platform-android',
'product_name': 'mbgl-platform-android',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'dependencies': [
'version',
],
'variables': {
'cflags_cc': [
'<@(png_cflags)',
'<@(jpeg_cflags)',
'<@(uv_cflags)',
'<@(curl_cflags)',
'<@(nu_cflags)',
'<@(zip_cflags)',
'<@(openssl_cflags)',
'-I<(boost_root)/include',
],
'cflags': [
'<@(uv_cflags)',
'<@(nu_cflags)',
],
'ldflags': [
'<@(png_ldflags)',
'<@(jpeg_ldflags)',
'<@(uv_ldflags)',
'<@(curl_ldflags)',
'<@(nu_ldflags)',
'<@(zip_ldflags)',
],
},
'sources': [
'../platform/android/log_android.cpp',
'../platform/android/asset_request_libzip.cpp',
'../platform/default/string_stdlib.cpp',
'../platform/default/http_request_baton_curl.cpp',
'../platform/default/image.cpp',
'../platform/default/image_reader.cpp',
'../platform/default/png_reader.cpp',
'../platform/default/jpeg_reader.cpp',
],
'variables': {
'cflags_cc': [
'<@(png_cflags)',
'<@(jpeg_cflags)',
'<@(uv_cflags)',
'<@(nu_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(png_ldflags)',
'<@(jpeg_ldflags)',
'<@(uv_ldflags)',
'<@(nu_ldflags)',
],
'libraries': [
'<@(png_static_libs)',
'<@(jpeg_static_libs)',
'<@(uv_static_libs)',
'<@(nu_static_libs)',
],
},
'include_dirs': [
'../include',
'../src',
],
'link_settings': {
'libraries': [
'<@(png_static_libs)',
'<@(jpeg_static_libs)',
'<@(nu_static_libs)'
],
},
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
'OTHER_CFLAGS': [ '<@(cflags)' ],
}
}, {
'cflags_cc': [ '<@(cflags_cc)' ],
'cflags': [ '<@(cflags)' ],
}]
],
'link_settings': {
'conditions': [
['OS == "mac"', {
'libraries': [ '<@(libraries)' ],
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
}, {
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
}]
],
},
'direct_dependent_settings': {
'include_dirs': [
'../include',
],
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
}
}, {
'ldflags': [ '<@(ldflags)' ],
}]
],
},
},
],

View File

@@ -1,7 +1,7 @@
{
'targets': [
{ 'target_name': 'mbgl-ios',
'product_name': 'mbgl-ios',
{ 'target_name': 'platform-ios',
'product_name': 'mbgl-platform-ios',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
@@ -13,6 +13,7 @@
'../platform/darwin/log_nslog.mm',
'../platform/darwin/string_nsstring.mm',
'../platform/darwin/application_root.mm',
'../platform/darwin/asset_root.mm',
'../platform/darwin/image.mm',
],

View File

@@ -1,7 +1,7 @@
{
'targets': [
{ 'target_name': 'mbgl-linux',
'product_name': 'mbgl-linux',
{ 'target_name': 'platform-linux',
'product_name': 'mbgl-platform-linux',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
@@ -13,6 +13,7 @@
'../platform/default/log_stderr.cpp',
'../platform/default/string_stdlib.cpp',
'../platform/default/application_root.cpp',
'../platform/default/asset_root.cpp',
'../platform/default/image.cpp',
'../platform/default/image_reader.cpp',
'../platform/default/png_reader.cpp',

View File

@@ -1,7 +1,7 @@
{
'targets': [
{ 'target_name': 'mbgl-osx',
'product_name': 'mbgl-osx',
{ 'target_name': 'platform-osx',
'product_name': 'mbgl-platform-osx',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
@@ -13,6 +13,7 @@
'../platform/darwin/log_nslog.mm',
'../platform/darwin/string_nsstring.mm',
'../platform/darwin/application_root.mm',
'../platform/darwin/asset_root.mm',
'../platform/darwin/image.mm',
],

32
gyp/standalone.gypi Normal file
View File

@@ -0,0 +1,32 @@
{
'targets': [
{ 'target_name': 'everything',
'type': 'none',
'hard_dependency': 1,
'dependencies': [
'core',
'platform-<(platform_lib)',
'http-<(http_lib)',
'asset-<(asset_lib)',
'cache-<(cache_lib)',
'headless-<(headless_lib)',
],
},
{ 'target_name': 'standalone',
'product_name': 'libmbgl.a',
'type': 'executable',
'hard_dependency': 1,
'dependencies': [
'core',
'platform-<(platform_lib)',
'http-<(http_lib)',
'asset-<(asset_lib)',
'cache-<(cache_lib)',
'headless-<(headless_lib)',
],
},
],
}

View File

@@ -1,32 +0,0 @@
{
'variables': {
'core_library%': 'mbgl-core',
'headless_library%': 'mbgl-headless',
},
'conditions': [
['platform == "osx"', {
'variables': {
'platform_library%': 'mbgl-osx',
'storage_library%': 'mbgl-storage-cocoa',
},
}],
['platform == "ios"', {
'variables': {
'platform_library%': 'mbgl-ios',
'storage_library%': 'mbgl-storage-cocoa',
},
}],
['platform == "linux"', {
'variables': {
'platform_library%': 'mbgl-linux',
'storage_library%': 'mbgl-storage-curl',
},
}],
['platform == "android"', {
'variables': {
'platform_library%': 'mbgl-android',
'storage_library%': 'mbgl-storage-curl',
},
}],
],
}

View File

@@ -2,7 +2,11 @@
#define MBGL_ANDROID_JNI
#include <string>
#include <jni.h>
// Forward definition of JNI types
typedef class _jclass* jclass;
typedef struct _jmethodID* jmethodID;
typedef struct _jfieldID* jfieldID;
namespace mbgl {
namespace android {

View File

@@ -4,7 +4,8 @@
#include <mbgl/map/map.hpp>
#include <mbgl/map/view.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/storage/caching_http_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <string>
#include <jni.h>
@@ -28,7 +29,7 @@ public:
void notifyMapChange(mbgl::MapChange change, std::chrono::steady_clock::duration delay = std::chrono::steady_clock::duration::zero()) override;
mbgl::Map &getMap();
mbgl::CachingHTTPFileSource &getFileSource();
mbgl::DefaultFileSource &getFileSource();
void initializeDisplay();
void terminateDisplay();
@@ -61,7 +62,8 @@ private:
ANativeWindow *window = nullptr;
mbgl::CachingHTTPFileSource fileSource;
mbgl::SQLiteCache fileCache;
mbgl::DefaultFileSource fileSource;
mbgl::Map map;
EGLDisplay display = EGL_NO_DISPLAY;

View File

@@ -20,6 +20,9 @@ std::string lowercase(const std::string &string);
// Returns the path to the root folder of the application.
const std::string &applicationRoot();
// Returns the path to the asset location.
const std::string &assetRoot();
// Shows an alpha image with the specified dimensions in a named window.
void show_debug_image(std::string name, const char *data, size_t width, size_t height);

View File

@@ -1,38 +0,0 @@
#ifndef MBGL_STORAGE_ASSET_REQUEST_BATON
#define MBGL_STORAGE_ASSET_REQUEST_BATON
#include <mbgl/util/uv.hpp>
#include <thread>
#include <uv.h>
namespace mbgl {
class AssetRequest;
struct AssetRequestBaton {
AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop);
const std::thread::id threadId;
AssetRequest *request = nullptr;
std::unique_ptr<uv::async> asyncRun;
std::string path;
bool canceled = false;
void cancel();
static void notifyError(AssetRequestBaton *ptr, const int code, const char *message);
static void notifySuccess(AssetRequestBaton *ptr, const std::string body);
static void cleanup(AssetRequestBaton *ptr);
// IMPLEMENT THIS PLATFORM SPECIFIC FUNCTION:
// Called to load the asset. Platform-specific implementation.
static void run(AssetRequestBaton *ptr);
};
}
#endif

View File

@@ -1,17 +1,9 @@
#ifndef MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
#define MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
#include "thread_context.hpp"
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/uv.hpp>
#include <uv.h>
#include <pthread.h>
#include <map>
#include <cassert>
#include <set>
namespace mbgl {
@@ -23,18 +15,7 @@ class HTTPRequest;
// triggers immediate retries on all requests waiting for network status changes.
template <typename Context>
class HTTPContext : private util::noncopyable {
protected:
MBGL_STORE_THREAD(tid)
using Map = std::map<uv_loop_t *, std::unique_ptr<Context>>;
public:
static Context *Get(uv_loop_t *loop);
private:
static pthread_key_t key;
static pthread_once_t once;
class HTTPContext : public ThreadContext<Context> {
public:
HTTPContext(uv_loop_t *loop);
~HTTPContext();
@@ -43,8 +24,6 @@ public:
void removeRequest(HTTPRequest *baton);
public:
uv_loop_t *loop;
// Will be fired when the network status becomes reachable.
uv_async_t *reachability = nullptr;
@@ -54,35 +33,15 @@ public:
};
template <typename Context>
Context *HTTPContext<Context>::Get(uv_loop_t *loop) {
pthread_once(&once, []() {
pthread_key_create(&key, [](void *ptr) {
assert(ptr);
delete reinterpret_cast<Map *>(ptr);
});
});
auto contexts = reinterpret_cast<Map *>(pthread_getspecific(key));
if (!contexts) {
contexts = new Map();
pthread_setspecific(key, contexts);
}
// Now find a HTTPContext that matches the requested loop.
auto it = contexts->find(loop);
if (it == contexts->end()) {
auto result = contexts->emplace(loop, util::make_unique<Context>(loop));
assert(result.second); // Make sure it was actually inserted.
return result.first->second.get();
} else {
return it->second.get();
}
}
template <typename Context>
HTTPContext<Context>::HTTPContext(uv_loop_t *loop_) : loop(loop_) {
HTTPContext<Context>::HTTPContext(uv_loop_t *loop_)
: ThreadContext<Context>(loop_) {
reachability = new uv_async_t;
reachability->data = this;
uv_async_init(loop, reachability, [](uv_async_t *async, int) {
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
uv_async_init(loop_, reachability, [](uv_async_t *async, int) {
#else
uv_async_init(loop_, reachability, [](uv_async_t *async) {
#endif
for (auto request : reinterpret_cast<Context *>(async->data)->requests) {
request->retryImmediately();
}
@@ -94,7 +53,7 @@ HTTPContext<Context>::HTTPContext(uv_loop_t *loop_) : loop(loop_) {
template <typename Context>
HTTPContext<Context>::~HTTPContext() {
MBGL_VERIFY_THREAD(tid);
MBGL_VERIFY_THREAD(HTTPContext<Context>::tid);
assert(requests.empty());

View File

@@ -33,8 +33,8 @@ public:
void cancel();
private:
static void notifyCallback(uv_async_t *async, int);
static void cancelCallback(uv_async_t *async, int);
static void notifyCallback(uv_async_t *async);
static void cancelCallback(uv_async_t *async);
private:
uv_async_t *notify_async = nullptr;

View File

@@ -3,11 +3,10 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/file_cache.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/noncopyable.hpp>
#include "default_file_source.hpp"
#include <string>
#include <set>
#include <cassert>

View File

@@ -0,0 +1,78 @@
#ifndef MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
#define MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/uv.hpp>
#include <uv.h>
#include <pthread.h>
#include <map>
#include <cassert>
namespace mbgl {
// This is a template class that provides a per-thread and per-loop Context object. It can be used
// by implementations to store global state.
template <typename Context>
class ThreadContext : private util::noncopyable {
protected:
MBGL_STORE_THREAD(tid)
using Map = std::map<uv_loop_t *, std::unique_ptr<Context>>;
public:
static Context *Get(uv_loop_t *loop);
private:
static pthread_key_t key;
static pthread_once_t once;
public:
ThreadContext(uv_loop_t *loop);
~ThreadContext();
public:
uv_loop_t *loop;
};
template <typename Context>
Context *ThreadContext<Context>::Get(uv_loop_t *loop) {
pthread_once(&once, []() {
pthread_key_create(&key, [](void *ptr) {
assert(ptr);
delete reinterpret_cast<Map *>(ptr);
});
});
auto contexts = reinterpret_cast<Map *>(pthread_getspecific(key));
if (!contexts) {
contexts = new Map();
pthread_setspecific(key, contexts);
}
// Now find a ThreadContext that matches the requested loop.
auto it = contexts->find(loop);
if (it == contexts->end()) {
auto result = contexts->emplace(loop, util::make_unique<Context>(loop));
assert(result.second); // Make sure it was actually inserted.
return result.first->second.get();
} else {
return it->second.get();
}
}
template <typename Context>
ThreadContext<Context>::ThreadContext(uv_loop_t *loop_) : loop(loop_) {
}
template <typename Context>
ThreadContext<Context>::~ThreadContext() {
MBGL_VERIFY_THREAD(tid);
}
}
#endif

View File

@@ -4,7 +4,7 @@
#include <mbgl/platform/default/settings_json.hpp>
#include <mbgl/platform/default/glfw_view.hpp>
#include <mbgl/platform/default/log_stderr.hpp>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
#include <signal.h>

View File

@@ -8,9 +8,11 @@
'type': 'executable',
'dependencies': [
'../mbgl.gyp:<(core_library)',
'../mbgl.gyp:<(platform_library)',
'../mbgl.gyp:<(storage_library)',
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
'../mbgl.gyp:bundle_styles',
'../mbgl.gyp:copy_certificate_bundle',
],

View File

@@ -3,7 +3,7 @@
#include <mbgl/platform/darwin/log_nslog.hpp>
#include <mbgl/platform/darwin/Reachability.h>
#include <mbgl/platform/default/glfw_view.hpp>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
#include <mbgl/storage/network_status.hpp>

View File

@@ -14,9 +14,11 @@
'dependencies': [
'../mbgl.gyp:bundle_styles',
'../mbgl.gyp:<(core_library)',
'../mbgl.gyp:<(platform_library)',
'../mbgl.gyp:<(storage_library)',
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
],
'sources': [

View File

@@ -5,34 +5,21 @@
'./gyp/version.gypi',
'./gyp/styles.gypi',
'./gyp/certificates.gypi',
'./gyp/mbgl-core.gypi',
'./gyp/mbgl-headless.gypi',
'./gyp/mbgl-standalone.gypi',
'./gyp/standalone.gypi',
'./gyp/core.gypi',
'./gyp/none.gypi',
],
'conditions': [
['platform == "osx"', {
'includes': [
'./gyp/mbgl-osx.gypi',
'./gyp/mbgl-storage-cocoa.gypi',
],
}],
['platform == "ios"', {
'includes': [
'./gyp/mbgl-ios.gypi',
'./gyp/mbgl-storage-cocoa.gypi',
],
}],
['platform == "linux"', {
'includes': [
'./gyp/mbgl-linux.gypi',
'./gyp/mbgl-storage-curl.gypi',
],
}],
['platform == "android"', {
'includes': [
'./gyp/mbgl-android.gypi'
],
}],
['headless_lib == "cgl"', { 'includes': [ './gyp/headless-cgl.gypi' ] } ],
['headless_lib == "glx"', { 'includes': [ './gyp/headless-glx.gypi' ] } ],
['platform_lib == "osx"', { 'includes': [ './gyp/platform-osx.gypi' ] } ],
['platform_lib == "ios"', { 'includes': [ './gyp/platform-ios.gypi' ] } ],
['platform_lib == "linux"', { 'includes': [ './gyp/platform-linux.gypi' ] } ],
['platform_lib == "android"', { 'includes': [ './gyp/platform-android.gypi' ] } ],
['http_lib == "curl"', { 'includes': [ './gyp/http-curl.gypi' ] } ],
['http_lib == "nsurl"', { 'includes': [ './gyp/http-nsurl.gypi' ] } ],
['asset_lib == "fs"', { 'includes': [ './gyp/asset-fs.gypi' ] } ],
['asset_lib == "zip"', { 'includes': [ './gyp/asset-zip.gypi' ] } ],
['cache_lib == "sqlite"', { 'includes': [ './gyp/cache-sqlite.gypi' ] } ],
],
}

View File

@@ -1,202 +0,0 @@
#include <mbgl/android/jni.hpp>
#include <mbgl/storage/asset_request.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/uv_detail.hpp>
#include <mbgl/util/std.hpp>
#include <cerrno>
// NOTE a bug in the Android NDK breaks std::errno
// See https://code.google.com/p/android/issues/detail?id=72349
// After this is fixed change usage errno to std::errno
#include <zip.h>
namespace mbgl {
struct AssetRequestBaton {
AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop);
~AssetRequestBaton();
const std::thread::id threadId;
AssetRequest *request = nullptr;
std::unique_ptr<uv::async> asyncRun;
std::string path;
bool canceled = false;
void cancel();
static void notifyError(AssetRequestBaton *ptr, const int code, const char *message);
static void notifySuccess(AssetRequestBaton *ptr, const std::string body);
static void cleanup(AssetRequestBaton *ptr);
static void run(AssetRequestBaton *ptr);
};
AssetRequestBaton::AssetRequestBaton(AssetRequest *request_, const std::string &path_, uv_loop_t *loop)
: threadId(std::this_thread::get_id()),
request(request_),
path(path_) {
asyncRun = mbgl::util::make_unique<uv::async>(loop, [this]() {
run(this);
});
asyncRun->send();
}
AssetRequestBaton::~AssetRequestBaton() {
}
void AssetRequestBaton::cancel() {
canceled = true;
}
void AssetRequestBaton::notifyError(AssetRequestBaton *ptr, const int code, const char *message) {
assert(std::this_thread::get_id() == ptr->threadId);
if (ptr->request && !ptr->canceled) {
ptr->request->response = std::unique_ptr<Response>(new Response);
ptr->request->response->code = code;
ptr->request->response->message = message;
ptr->request->notify();
}
}
void AssetRequestBaton::notifySuccess(AssetRequestBaton *ptr, const std::string body) {
assert(std::this_thread::get_id() == ptr->threadId);
if (ptr->request && !ptr->canceled) {
ptr->request->response = std::unique_ptr<Response>(new Response);
ptr->request->response->code = 200;
ptr->request->response->data = body;
ptr->request->notify();
}
}
void AssetRequestBaton::cleanup(AssetRequestBaton *ptr) {
assert(std::this_thread::get_id() == ptr->threadId);
if (ptr->request) {
ptr->request->ptr = nullptr;
}
ptr->asyncRun.reset();
delete ptr;
ptr = nullptr;
}
void AssetRequestBaton::run(AssetRequestBaton *ptr) {
assert(std::this_thread::get_id() == ptr->threadId);
if (ptr->canceled || !ptr->request) {
// Either the AssetRequest object has been destructed, or the
// request was canceled.
cleanup(ptr);
return;
}
int error = 0;
struct zip *apk = zip_open(mbgl::android::apkPath.c_str(), 0, &error);
if ((apk == nullptr) || ptr->canceled || !ptr->request) {
// Opening the APK failed or was canceled. There isn't much left we can do.
const int messageSize = zip_error_to_str(nullptr, 0, error, errno);
const std::unique_ptr<char[]> message = mbgl::util::make_unique<char[]>(messageSize);
zip_error_to_str(message.get(), 0, error, errno);
notifyError(ptr, 500, message.get());
cleanup(ptr);
return;
}
std::string apkFilePath = "assets/" + ptr->path;
struct zip_file *apkFile = zip_fopen(apk, apkFilePath.c_str(), ZIP_FL_NOCASE);
if ((apkFile == nullptr) || ptr->canceled || !ptr->request) {
// Opening the asset failed or was canceled. We already have an open file handle
// though, which we'll have to close.
zip_error_get(apk, &error, nullptr);
notifyError(ptr, error == ZIP_ER_NOENT ? 404 : 500, zip_strerror(apk));
zip_close(apk);
apk = nullptr;
cleanup(ptr);
return;
}
struct zip_stat stat;
if ((zip_stat(apk, apkFilePath.c_str(), ZIP_FL_NOCASE, &stat) != 0) || ptr->canceled || !ptr->request) {
// Stating failed or was canceled. We already have an open file handle
// though, which we'll have to close.
notifyError(ptr, 500, zip_strerror(apk));
zip_fclose(apkFile);
apkFile = nullptr;
zip_close(apk);
apk = nullptr;
cleanup(ptr);
return;
}
const std::unique_ptr<char[]> data = mbgl::util::make_unique<char[]>(stat.size);
if (static_cast<zip_uint64_t>(zip_fread(apkFile, reinterpret_cast<void *>(data.get()), stat.size)) != stat.size || ptr->canceled || !ptr->request) {
// Reading failed or was canceled. We already have an open file handle
// though, which we'll have to close.
notifyError(ptr, 500, zip_file_strerror(apkFile));
zip_fclose(apkFile);
apkFile = nullptr;
zip_close(apk);
apk = nullptr;
cleanup(ptr);
return;
}
std::string body(data.get(), stat.size);
notifySuccess(ptr, body);
if (zip_fclose(apkFile) != 0) {
// Closing the asset failed. But there isn't anything we can do.
}
apkFile = nullptr;
if (zip_close(apk) != 0) {
// Closing the APK failed. But there isn't anything we can do.
}
apk = nullptr;
cleanup(ptr);
}
AssetRequest::AssetRequest(const std::string &path_, uv_loop_t *loop)
: BaseRequest(path_) {
if (!path.empty() && path[0] == '/') {
// This is an absolute path. We don't allow this. Note that this is not a way to absolutely
// prevent access to resources outside the application bundle; e.g. there could be symlinks
// in the application bundle that link to outside. We don't care about these.
response = util::make_unique<Response>();
response->code = 403;
response->message = "Path is outside the application bundle";
notify();
} else {
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
ptr = new AssetRequestBaton(this, path, loop);
}
}
void AssetRequest::cancel() {
assert(std::this_thread::get_id() == threadId);
if (ptr) {
ptr->cancel();
// When deleting a AssetRequest object with a uv_fs_* call is in progress, we are making sure
// that the callback doesn't accidentally reference this object again.
ptr->request = nullptr;
ptr = nullptr;
}
notify();
}
AssetRequest::~AssetRequest() {
assert(std::this_thread::get_id() == threadId);
cancel();
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
}
}

View File

@@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>
#include <mbgl/platform/platform.hpp>
namespace mbgl {
namespace platform {
// Returns the path to the root folder of the application.
const std::string &assetRoot() {
static const std::string root = []() -> std::string {
NSString *path = [[[NSBundle mainBundle] resourceURL] path];
return {[path cStringUsingEncoding : NSUTF8StringEncoding],
[path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
}();
return root;
}
}
}

View File

@@ -43,7 +43,7 @@ enum class ResponseStatus : uint8_t {
// -------------------------------------------------------------------------------------------------
class HTTPCocoaContext;
class HTTPNSURLContext;
class HTTPRequestImpl {
public:
@@ -62,7 +62,7 @@ public:
static void restart(uv_timer_t *timer, int);
private:
HTTPCocoaContext *context = nullptr;
HTTPNSURLContext *context = nullptr;
HTTPRequest *request = nullptr;
NSURLSessionDataTask *task = nullptr;
std::unique_ptr<Response> response;
@@ -78,19 +78,19 @@ private:
// -------------------------------------------------------------------------------------------------
class HTTPCocoaContext : public HTTPContext<HTTPCocoaContext> {
class HTTPNSURLContext : public HTTPContext<HTTPNSURLContext> {
public:
HTTPCocoaContext(uv_loop_t *loop);
~HTTPCocoaContext();
HTTPNSURLContext(uv_loop_t *loop);
~HTTPNSURLContext();
NSURLSession *session = nil;
NSString *userAgent = nil;
};
template<> pthread_key_t HTTPContext<HTTPCocoaContext>::key{};
template<> pthread_once_t HTTPContext<HTTPCocoaContext>::once = PTHREAD_ONCE_INIT;
template<> pthread_key_t ThreadContext<HTTPNSURLContext>::key{};
template<> pthread_once_t ThreadContext<HTTPNSURLContext>::once = PTHREAD_ONCE_INIT;
HTTPCocoaContext::HTTPCocoaContext(uv_loop_t *loop_) : HTTPContext(loop_) {
HTTPNSURLContext::HTTPNSURLContext(uv_loop_t *loop_) : HTTPContext(loop_) {
@autoreleasepool {
NSURLSessionConfiguration *sessionConfig =
[NSURLSessionConfiguration defaultSessionConfiguration];
@@ -107,7 +107,7 @@ HTTPCocoaContext::HTTPCocoaContext(uv_loop_t *loop_) : HTTPContext(loop_) {
}
}
HTTPCocoaContext::~HTTPCocoaContext() {
HTTPNSURLContext::~HTTPNSURLContext() {
[session release];
session = nullptr;
@@ -119,7 +119,7 @@ HTTPCocoaContext::~HTTPCocoaContext() {
HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop,
std::unique_ptr<Response> existingResponse_)
: context(HTTPCocoaContext::Get(loop)),
: context(HTTPNSURLContext::Get(loop)),
request(request_),
existingResponse(std::move(existingResponse_)),
async(new uv_async_t) {

View File

@@ -56,7 +56,7 @@ AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : re
path = url.substr(8);
} else {
// This is a relative path. Prefix with the application root.
path = platform::applicationRoot() + "/" + url.substr(8);
path = platform::assetRoot() + "/" + url.substr(8);
}
uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened);

View File

@@ -0,0 +1,295 @@
#include <mbgl/storage/default/asset_request.hpp>
#include <mbgl/storage/default/thread_context.hpp>
#include <mbgl/android/jni.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/platform/platform.hpp>
#include "uv_zip.h"
#include <boost/algorithm/string.hpp>
#include <forward_list>
namespace algo = boost::algorithm;
namespace mbgl {
class AssetZipContext : public ThreadContext<AssetZipContext> {
public:
AssetZipContext(uv_loop_t *loop);
~AssetZipContext();
uv_zip_t *getHandle();
void returnHandle(uv_zip_t *zip);
private:
// A list of resuable uv_zip handles to avoid creating and destroying them all the time.
std::forward_list<uv_zip_t *> handles;
};
// -------------------------------------------------------------------------------------------------
template<> pthread_key_t ThreadContext<AssetZipContext>::key{};
template<> pthread_once_t ThreadContext<AssetZipContext>::once = PTHREAD_ONCE_INIT;
AssetZipContext::AssetZipContext(uv_loop_t *loop_) : ThreadContext(loop_) {
}
uv_zip_t *AssetZipContext::getHandle() {
if (!handles.empty()) {
auto zip = handles.front();
handles.pop_front();
return zip;
} else {
return nullptr;
}
}
void AssetZipContext::returnHandle(uv_zip_t *zip) {
uv_zip_cleanup(zip);
handles.push_front(zip);
}
AssetZipContext::~AssetZipContext() {
// Close all zip handles
for (auto zip : handles) {
uv_zip_discard(loop, zip, [](uv_zip_t *zip_) {
uv_zip_cleanup(zip_);
delete zip_;
});
}
handles.clear();
}
// -------------------------------------------------------------------------------------------------
class AssetRequestImpl {
MBGL_STORE_THREAD(tid)
public:
AssetRequestImpl(AssetRequest *request, uv_loop_t *loop);
~AssetRequestImpl();
void cancel();
private:
AssetZipContext &context;
AssetRequest *request = nullptr;
const std::string path;
std::unique_ptr<Response> response;
uv_buf_t buffer;
private:
void openZipArchive();
void archiveOpened(uv_zip_t *zip);
void fileStated(uv_zip_t *zip);
void fileOpened(uv_zip_t *zip);
void fileRead(uv_zip_t *zip);
void fileClosed(uv_zip_t *zip);
void cleanup(uv_zip_t *zip);
void notifyError(const char *message);
};
// -------------------------------------------------------------------------------------------------
AssetRequestImpl::~AssetRequestImpl() {
MBGL_VERIFY_THREAD(tid);
if (request) {
request->ptr = nullptr;
}
}
AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop)
: context(*AssetZipContext::Get(loop)),
request(request_),
path(request->resource.url.substr(8)) {
auto zip = context.getHandle();
if (zip) {
archiveOpened(zip);
} else {
openZipArchive();
}
}
void AssetRequestImpl::openZipArchive() {
uv_fs_t *req = new uv_fs_t();
req->data = this;
// We're using uv_fs_open first to obtain a file descriptor. Then, uv_zip_fdopen will operate
// on a read-only file.
uv_fs_open(context.loop, req, platform::assetRoot().c_str(), O_RDONLY, S_IRUSR, [](uv_fs_t *fsReq) {
if (fsReq->result < 0) {
auto impl = reinterpret_cast<AssetRequestImpl *>(fsReq->data);
impl->notifyError(uv::getFileRequestError(fsReq));
delete impl;
} else {
uv_zip_t *zip = new uv_zip_t();
uv_zip_init(zip);
zip->data = fsReq->data;
uv_zip_fdopen(fsReq->loop, zip, uv_file(fsReq->result), 0, [](uv_zip_t *openZip) {
auto impl = reinterpret_cast<AssetRequestImpl *>(openZip->data);
if (openZip->result < 0) {
impl->notifyError(openZip->message);
delete openZip;
delete impl;
} else {
impl->archiveOpened(openZip);
}
});
}
uv_fs_req_cleanup(fsReq);
delete fsReq;
fsReq = nullptr;
});
}
#define INVOKE_MEMBER(name) \
[](uv_zip_t *zip_) { \
assert(zip_->data); \
reinterpret_cast<AssetRequestImpl *>(zip_->data)->name(zip_); \
}
void AssetRequestImpl::archiveOpened(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
zip->data = this;
uv_zip_stat(context.loop, zip, path.c_str(), 0, INVOKE_MEMBER(fileStated));
}
void AssetRequestImpl::fileStated(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
if (!request || zip->result < 0) {
// Stat failed, probably because the file doesn't exist.
if (zip->result < 0) {
notifyError(zip->message);
}
cleanup(zip);
} else if (!(zip->stat->valid & ZIP_STAT_SIZE)) {
// We couldn't obtain the size of the file.
notifyError("Could not determine file size in zip file");
cleanup(zip);
} else {
response = util::make_unique<Response>();
// Allocate the space for reading the data.
response->data.resize(zip->stat->size);
buffer = uv_buf_init(const_cast<char *>(response->data.data()), zip->stat->size);
// Get the modification time in case we have one.
if (zip->stat->valid & ZIP_STAT_MTIME) {
response->modified = zip->stat->mtime;
}
uv_zip_fopen(context.loop, zip, path.c_str(), 0, INVOKE_MEMBER(fileOpened));
}
}
void AssetRequestImpl::fileOpened(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
if (zip->result < 0) {
// Opening failed.
notifyError(zip->message);
cleanup(zip);
} else if (!request) {
// The request was canceled. Close the file again.
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
} else {
uv_zip_fread(context.loop, zip, zip->file, &buffer, INVOKE_MEMBER(fileRead));
}
}
void AssetRequestImpl::fileRead(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
if (zip->result < 0) {
// Reading failed. We still have an open file handle though.
notifyError(zip->message);
} else if (request) {
response->status = Response::Successful;
request->notify(std::move(response), FileCache::Hint::No);
delete request;
assert(request == nullptr);
}
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
}
void AssetRequestImpl::fileClosed(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
if (zip->result < 0) {
// Closing the file failed. But there isn't anything we can do.
}
cleanup(zip);
}
void AssetRequestImpl::cleanup(uv_zip_t *zip) {
MBGL_VERIFY_THREAD(tid);
context.returnHandle(zip);
delete this;
}
void AssetRequestImpl::notifyError(const char *message) {
MBGL_VERIFY_THREAD(tid);
if (request) {
response = util::make_unique<Response>();
response->status = Response::Error;
response->message = message;
request->notify(std::move(response), FileCache::Hint::No);
delete request;
assert(request == nullptr);
} else {
// The request was already canceled and deleted.
}
}
void AssetRequestImpl::cancel() {
request = nullptr;
}
// -------------------------------------------------------------------------------------------------
AssetRequest::AssetRequest(DefaultFileSource *source_, const Resource &resource_)
: SharedRequestBase(source_, resource_) {
assert(algo::starts_with(resource.url, "asset://"));
}
AssetRequest::~AssetRequest() {
MBGL_VERIFY_THREAD(tid);
if (ptr) {
reinterpret_cast<AssetRequestImpl *>(ptr)->cancel();
}
}
void AssetRequest::start(uv_loop_t *loop, std::unique_ptr<Response> response) {
MBGL_VERIFY_THREAD(tid);
// We're ignoring the existing response if any.
(void(response));
assert(!ptr);
ptr = new AssetRequestImpl(this, loop);
// Note: the AssetRequestImpl deletes itself.
}
void AssetRequest::cancel() {
MBGL_VERIFY_THREAD(tid);
if (ptr) {
reinterpret_cast<AssetRequestImpl *>(ptr)->cancel();
}
delete this;
}
}

View File

@@ -0,0 +1,28 @@
#include <mbgl/platform/platform.hpp>
#include <uv.h>
#include <libgen.h>
namespace mbgl {
namespace platform {
// Returns the path to the root folder of the application.
const std::string &assetRoot() {
static const std::string root = []() -> std::string {
size_t max = 0;
std::string dir;
do {
// Gradually increase the length of the string in case the path was truncated.
max += 256;
dir.resize(max);
uv_exepath(const_cast<char *>(dir.data()), &max);
} while (max == dir.size());
dir.resize(max - 1);
dir = dirname(const_cast<char *>(dir.c_str()));
return dir;
}();
return root;
}
}
}

View File

@@ -99,7 +99,11 @@ private:
static size_t writeCallback(void *const contents, const size_t size, const size_t nmemb, void *userp);
void retry(uint64_t timeout);
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
static void restart(uv_timer_t *timer, int);
#else
static void restart(uv_timer_t *timer);
#endif
void finish(ResponseStatus status);
void start();
@@ -161,8 +165,8 @@ private:
// -------------------------------------------------------------------------------------------------
template<> pthread_key_t HTTPContext<HTTPCURLContext>::key{};
template<> pthread_once_t HTTPContext<HTTPCURLContext>::once = PTHREAD_ONCE_INIT;
template<> pthread_key_t ThreadContext<HTTPCURLContext>::key{};
template<> pthread_once_t ThreadContext<HTTPCURLContext>::once = PTHREAD_ONCE_INIT;
HTTPCURLContext::HTTPCURLContext(uv_loop_t *loop_) : HTTPContext(loop_) {
if (curl_global_init(CURL_GLOBAL_ALL)) {
@@ -491,7 +495,11 @@ void HTTPRequestImpl::retryImmediately() {
}
}
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
void HTTPRequestImpl::restart(uv_timer_t *timer, int) {
#else
void HTTPRequestImpl::restart(uv_timer_t *timer) {
#endif
// Restart the request.
auto baton = reinterpret_cast<HTTPRequestImpl *>(timer->data);

202
platform/default/uv_zip.c Normal file
View File

@@ -0,0 +1,202 @@
#include "uv_zip.h"
#include <assert.h>
#include <errno.h>
#include <string.h>
void uv__zip_open_error(uv_zip_t *zip, int error) {
zip->result = -error;
if (zip->message) {
free((char *)zip->message);
zip->message = NULL;
}
const zip_uint64_t size = zip_error_to_str(NULL, 0, error, errno) + 1;
zip->message = malloc(size);
zip_error_to_str((char *)zip->message, size, error, errno);
}
void uv__zip_store_error(uv_zip_t *zip, const char *message) {
if (zip->message) {
free((char *)zip->message);
zip->message = NULL;
}
const unsigned long length = strlen(message);
zip->message = malloc(length);
strncpy((char *)zip->message, message, length);
}
void uv__zip_error(uv_zip_t *zip) {
int error;
zip_error_get(zip->archive, &error, NULL);
zip->result = -error;
uv__zip_store_error(zip, zip_strerror(zip->archive));
}
void uv__zip_file_error(uv_zip_t *zip) {
int error;
zip_file_error_get(zip->file, &error, NULL);
zip->result = -error;
uv__zip_store_error(zip, zip_file_strerror(zip->file));
}
void uv__zip_work_open(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(!zip->archive);
int error;
zip->archive = zip_open(zip->path, zip->flags, &error);
if (!zip->archive) {
uv__zip_open_error(zip, error);
} else {
zip->result = 0;
}
}
void uv__zip_work_fdopen(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(!zip->archive);
// extract the fd
uv_file fd = *(uv_file *)zip->path;
free((uv_file *)zip->path);
zip->path = NULL;
int error;
zip->archive = zip_fdopen(fd, zip->flags, &error);
if (!zip->archive) {
uv__zip_open_error(zip, error);
} else {
zip->result = 0;
}
}
void uv__zip_work_stat(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(zip->archive);
if (!zip->stat) {
zip->stat = malloc(sizeof(struct zip_stat));
zip_stat_init(zip->stat);
}
if (0 != zip_stat(zip->archive, zip->path, zip->flags, zip->stat)) {
uv__zip_error(zip);
}
}
void uv__zip_work_fopen(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(zip->archive);
zip->file = zip_fopen(zip->archive, zip->path, zip->flags);
if (!zip->file) {
uv__zip_error(zip);
}
}
void uv__zip_work_fread(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(zip->file);
assert(zip->buf);
zip->result = zip_fread(zip->file, zip->buf->base, zip->buf->len);
if (zip->result < 0) {
uv__zip_file_error(zip);
}
}
void uv__zip_work_fclose(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(zip->file);
zip->result = zip_fclose(zip->file);
if (zip->result != 0) {
uv__zip_file_error(zip);
}
}
void uv__zip_work_discard(uv_work_t *req) {
uv_zip_t *zip = (uv_zip_t *)req->data;
assert(zip->archive);
zip_discard(zip->archive);
zip->archive = NULL;
zip->result = 0;
}
void uv__zip_after_work(uv_work_t *req, int status) {
uv_zip_t *zip = (uv_zip_t *)req->data;
if (zip->cb) {
zip->cb(zip);
}
}
void uv_zip_init(uv_zip_t *zip) {
zip->work.data = zip;
zip->message = NULL;
zip->stat = NULL;
uv_zip_cleanup(zip);
}
void uv_zip_cleanup(uv_zip_t *zip) {
zip->data = NULL;
zip->flags = 0;
zip->result = 0;
zip->path = NULL;
zip->cb = NULL;
zip->archive = NULL;
zip->file = NULL;
zip->buf = NULL;
if (zip->message) {
free((char *)zip->message);
zip->message = NULL;
}
if (zip->stat) {
free(zip->stat);
zip->stat = NULL;
}
}
int uv_zip_open(uv_loop_t* loop, uv_zip_t *zip, const char *path, zip_flags_t flags, uv_zip_cb cb) {
zip->path = path;
zip->flags = flags;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_open, uv__zip_after_work);
}
int uv_zip_fdopen(uv_loop_t* loop, uv_zip_t *zip, uv_file fd, int flags, uv_zip_cb cb) {
zip->path = malloc(sizeof(uv_file));
*(uv_file *)zip->path = fd;
zip->flags = flags;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_fdopen, uv__zip_after_work);
}
int uv_zip_stat(uv_loop_t* loop, uv_zip_t *zip, const char *fname, zip_flags_t flags, uv_zip_cb cb) {
zip->path = fname;
zip->flags = flags;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_stat, uv__zip_after_work);
}
int uv_zip_fopen(uv_loop_t* loop, uv_zip_t *zip, const char *fname, zip_flags_t flags, uv_zip_cb cb) {
zip->path = fname;
zip->flags = flags;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_fopen, uv__zip_after_work);
}
int uv_zip_fclose(uv_loop_t* loop, uv_zip_t *zip, struct zip_file *file, uv_zip_cb cb) {
zip->file = file;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_fclose, uv__zip_after_work);
}
int uv_zip_fread(uv_loop_t* loop, uv_zip_t *zip, struct zip_file *file, uv_buf_t *buf, uv_zip_cb cb) {
zip->file = file;
zip->buf = buf;
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_fread, uv__zip_after_work);
}
int uv_zip_discard(uv_loop_t* loop, uv_zip_t *zip, uv_zip_cb cb) {
zip->cb = cb;
return uv_queue_work(loop, &zip->work, uv__zip_work_discard, uv__zip_after_work);
}

45
platform/default/uv_zip.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef UV_ZIP
#define UV_ZIP
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <uv.h>
#include <zip.h>
typedef struct uv_zip_s uv_zip_t;
typedef void (*uv_zip_cb)(uv_zip_t* req);
struct uv_zip_s {
uv_work_t work;
ssize_t result;
const char *message;
struct zip *archive;
struct zip_file *file;
struct zip_stat *stat;
void *data;
zip_flags_t flags;
const char *path;
uv_zip_cb cb;
uv_buf_t *buf;
};
void uv_zip_init(uv_zip_t *zip);
void uv_zip_cleanup(uv_zip_t *zip);
int uv_zip_open(uv_loop_t* loop, uv_zip_t *zip, const char *path, zip_flags_t flags, uv_zip_cb cb);
int uv_zip_fdopen(uv_loop_t* loop, uv_zip_t *zip, uv_file fd, int flags, uv_zip_cb cb);
int uv_zip_stat(uv_loop_t* loop, uv_zip_t *zip, const char *fname, zip_flags_t flags, uv_zip_cb cb);
int uv_zip_fopen(uv_loop_t* loop, uv_zip_t *zip, const char *fname, zip_flags_t flags, uv_zip_cb cb);
int uv_zip_fread(uv_loop_t* loop, uv_zip_t *zip, struct zip_file *file, uv_buf_t *buf, uv_zip_cb cb);
int uv_zip_fclose(uv_loop_t* loop, uv_zip_t *zip, struct zip_file *file, uv_zip_cb cb);
int uv_zip_discard(uv_loop_t* loop, uv_zip_t *zip, uv_zip_cb cb);
#ifdef __cplusplus
}
#endif
#endif // UV_ZIP

20
scripts/android_env.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
set -o pipefail
./scripts/local_mason.sh
echo CXX=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env CXX`"\"
echo CC=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env CC`"\"
echo LD=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env LD`"\"
echo LINK=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env CXX`"\"
echo AR=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env AR`"\"
echo RANLIB=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env RANLIB`"\"
echo LDFLAGS=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env LDFLAGS` ${LDFLAGS}"\"
echo CFLAGS=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env CFLAGS` ${CFLAGS}"\"
echo CPPFLAGS=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env CPPFLAGS` ${CPPFLAGS}"\"
echo PATH=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env PATH`"\"
echo JNIDIR=\""`MASON_DIR=.mason MASON_PLATFORM=android .mason/mason env JNIDIR`"\"
echo MASON_PLATFORM=\"android\"

View File

@@ -1,27 +0,0 @@
#ifndef MBGL_STORAGE_ASSET_REQUEST
#define MBGL_STORAGE_ASSET_REQUEST
#include <mbgl/storage/base_request.hpp>
namespace mbgl {
typedef struct uv_loop_s uv_loop_t;
struct AssetRequestBaton;
class AssetRequest : public BaseRequest {
public:
AssetRequest(const std::string &path, uv_loop_t *loop);
~AssetRequest();
void cancel();
private:
AssetRequestBaton *ptr = nullptr;
friend struct AssetRequestBaton;
};
}
#endif

View File

@@ -1,4 +1,4 @@
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/request.hpp>
#include <mbgl/storage/default/asset_request.hpp>
#include <mbgl/storage/default/http_request.hpp>

View File

@@ -20,11 +20,15 @@ Request::Request(const Resource &resource_, uv_loop_t *loop, Callback callback_)
if (loop) {
notify_async = new uv_async_t;
notify_async->data = this;
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
uv_async_init(loop, notify_async, [](uv_async_t *async, int) { notifyCallback(async); });
#else
uv_async_init(loop, notify_async, notifyCallback);
#endif
}
}
void Request::notifyCallback(uv_async_t *async, int) {
void Request::notifyCallback(uv_async_t *async) {
auto request = reinterpret_cast<Request *>(async->data);
uv::close(async);
@@ -67,10 +71,14 @@ void Request::cancel() {
assert(!destruct_async);
destruct_async = new uv_async_t;
destruct_async->data = this;
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
uv_async_init(notify_async->loop, destruct_async, [](uv_async_t *async, int) { cancelCallback(async); });
#else
uv_async_init(notify_async->loop, destruct_async, cancelCallback);
#endif
}
void Request::cancelCallback(uv_async_t *async, int) {
void Request::cancelCallback(uv_async_t *async) {
// The destruct_async will be invoked *after* the notify_async callback has already run.
auto request = reinterpret_cast<Request *>(async->data);
uv::close(async);

View File

@@ -12,7 +12,7 @@
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <dirent.h>

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
TEST_F(Storage, CacheResponse) {

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
TEST_F(Storage, CacheRevalidate) {

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
TEST_F(Storage, ReadDirectory) {
SCOPED_TEST(ReadDirectory)

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/platform/platform.hpp>
TEST_F(Storage, EmptyFile) {

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <cmath>

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
TEST_F(Storage, HTTPCoalescing) {
SCOPED_TEST(HTTPCoalescing)

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <cmath>

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <cmath>

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
TEST_F(Storage, HTTPLoad) {
SCOPED_TEST(HTTPLoad)

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/uv.hpp>
TEST_F(Storage, HTTPNoLoop) {

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
TEST_F(Storage, HTTPOtherLoop) {
SCOPED_TEST(HTTPOtherLoop)

View File

@@ -2,7 +2,7 @@
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default_file_source.hpp>
TEST_F(Storage, HTTPReading) {
SCOPED_TEST(HTTPTest)

View File

@@ -20,10 +20,12 @@
'include_dirs': [ '../include', '../src' ],
'dependencies': [
'symlink_TEST_DATA',
'../mbgl.gyp:<(core_library)',
'../mbgl.gyp:<(platform_library)',
'../mbgl.gyp:<(storage_library)',
'../mbgl.gyp:<(headless_library)',
'../mbgl.gyp:core',
'../mbgl.gyp:platform-<(platform_lib)',
'../mbgl.gyp:http-<(http_lib)',
'../mbgl.gyp:asset-<(asset_lib)',
'../mbgl.gyp:cache-<(cache_lib)',
'../mbgl.gyp:headless-<(headless_lib)',
'../deps/gtest/gtest.gyp:gtest'
],
'sources': [