diff options
68 files changed, 1309 insertions, 682 deletions
@@ -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 ########################################################### diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index d3934921b6..122ec794d6 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -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(); + } } } diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index bf9a3a0532..cd3445e24e 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -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 diff --git a/android/mapboxgl-app.gyp b/android/mapboxgl-app.gyp index 60ec22164d..71bd4f920a 100644 --- a/android/mapboxgl-app.gyp +++ b/android/mapboxgl-app.gyp @@ -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)' diff --git a/bin/render.cpp b/bin/render.cpp index ba17498c88..827f247d6c 100644 --- a/bin/render.cpp +++ b/bin/render.cpp @@ -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); diff --git a/bin/render.gyp b/bin/render.gyp index 71b36fba5e..4529cd12ab 100644 --- a/bin/render.gyp +++ b/bin/render.gyp @@ -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)' ], + }] ], }, ], @@ -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 diff --git a/gyp/asset-fs.gypi b/gyp/asset-fs.gypi new file mode 100644 index 0000000000..9cd8593fbc --- /dev/null +++ b/gyp/asset-fs.gypi @@ -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)' ], + }] + ], + }, + }, + ], +} diff --git a/gyp/asset-zip.gypi b/gyp/asset-zip.gypi new file mode 100644 index 0000000000..87f7584772 --- /dev/null +++ b/gyp/asset-zip.gypi @@ -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)' ], + }] + ], + }, + }, + ], +} diff --git a/gyp/mbgl-storage-curl.gypi b/gyp/cache-sqlite.gypi index f500d813e5..53af8dab59 100644 --- a/gyp/mbgl-storage-curl.gypi +++ b/gyp/cache-sqlite.gypi @@ -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)', ], }, diff --git a/gyp/common.gypi b/gyp/common.gypi index 2e47dd2f60..301856c52f 100644 --- a/gyp/common.gypi +++ b/gyp/common.gypi @@ -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', diff --git a/gyp/mbgl-core.gypi b/gyp/core.gypi index 5e6344da1c..0adcaa766f 100644 --- a/gyp/mbgl-core.gypi +++ b/gyp/core.gypi @@ -1,6 +1,6 @@ { 'targets': [ - { 'target_name': 'mbgl-core', + { 'target_name': 'core', 'product_name': 'mbgl-core', 'type': 'static_library', 'standalone_static_library': 1, diff --git a/gyp/mbgl-headless.gypi b/gyp/headless-cgl.gypi index df91e71698..bcb677c6ed 100644 --- a/gyp/mbgl-headless.gypi +++ b/gyp/headless-cgl.gypi @@ -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, diff --git a/gyp/headless-glx.gypi b/gyp/headless-glx.gypi new file mode 100644 index 0000000000..06062be75f --- /dev/null +++ b/gyp/headless-glx.gypi @@ -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', + ], + }, + ], +} diff --git a/gyp/http-curl.gypi b/gyp/http-curl.gypi new file mode 100644 index 0000000000..5dcd71a59b --- /dev/null +++ b/gyp/http-curl.gypi @@ -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)' ], + }] + ], + }, + }, + ], +} diff --git a/gyp/http-nsurl.gypi b/gyp/http-nsurl.gypi new file mode 100644 index 0000000000..4205f59d81 --- /dev/null +++ b/gyp/http-nsurl.gypi @@ -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)' ], + }, + }, + }, + ], +} diff --git a/gyp/install.gypi b/gyp/install.gypi index 48a7a997db..f42ffbf238 100644 --- a/gyp/install.gypi +++ b/gyp/install.gypi @@ -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)', diff --git a/gyp/load.gypi b/gyp/load.gypi new file mode 100644 index 0000000000..3d666ac938 --- /dev/null +++ b/gyp/load.gypi @@ -0,0 +1,6 @@ +{ + 'conditions': [ + ['platform_library == "mbglosx"', { + }], + ], +}
\ No newline at end of file diff --git a/gyp/mbgl-standalone.gypi b/gyp/mbgl-standalone.gypi deleted file mode 100644 index eb38a3e8c8..0000000000 --- a/gyp/mbgl-standalone.gypi +++ /dev/null @@ -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)', - ], - }, - ], -}
\ No newline at end of file diff --git a/gyp/mbgl-storage-cocoa.gypi b/gyp/mbgl-storage-cocoa.gypi deleted file mode 100644 index c22216b823..0000000000 --- a/gyp/mbgl-storage-cocoa.gypi +++ /dev/null @@ -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', - ], - }, - }, - ], -} diff --git a/gyp/none.gypi b/gyp/none.gypi new file mode 100644 index 0000000000..ce748bfe6f --- /dev/null +++ b/gyp/none.gypi @@ -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', + }, + ], +} diff --git a/gyp/mbgl-android.gypi b/gyp/platform-android.gypi index 17ce85eab2..ac86f50e65 100644 --- a/gyp/mbgl-android.gypi +++ b/gyp/platform-android.gypi @@ -1,83 +1,76 @@ { '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', ], + + 'sources': [ + '../platform/android/log_android.cpp', + '../platform/default/string_stdlib.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)', - '<@(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', - ], - 'include_dirs': [ - '../include', - '../src', - ], - 'link_settings': { 'libraries': [ '<@(png_static_libs)', '<@(jpeg_static_libs)', - '<@(nu_static_libs)' + '<@(uv_static_libs)', + '<@(nu_static_libs)', ], }, + + 'include_dirs': [ + '../include', + '../src', + ], + 'conditions': [ ['OS == "mac"', { 'xcode_settings': { 'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ], - 'OTHER_CFLAGS': [ '<@(cflags)' ], } }, { 'cflags_cc': [ '<@(cflags_cc)' ], - 'cflags': [ '<@(cflags)' ], }] ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../include', - ], + + 'link_settings': { 'conditions': [ ['OS == "mac"', { - 'xcode_settings': { - 'OTHER_LDFLAGS': [ '<@(ldflags)' ], - } + 'libraries': [ '<@(libraries)' ], + 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] } }, { - 'ldflags': [ '<@(ldflags)' ], + 'libraries': [ '<@(libraries)', '<@(ldflags)' ], }] ], }, + + 'direct_dependent_settings': { + 'include_dirs': [ + '../include', + ], + }, }, ], } diff --git a/gyp/mbgl-ios.gypi b/gyp/platform-ios.gypi index c2a7b6ca70..2bbe1272d2 100644 --- a/gyp/mbgl-ios.gypi +++ b/gyp/platform-ios.gypi @@ -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', ], diff --git a/gyp/mbgl-linux.gypi b/gyp/platform-linux.gypi index 930cd6fb17..2915606ac5 100644 --- a/gyp/mbgl-linux.gypi +++ b/gyp/platform-linux.gypi @@ -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', diff --git a/gyp/mbgl-osx.gypi b/gyp/platform-osx.gypi index d90d88ef43..1fdf9de2c7 100644 --- a/gyp/mbgl-osx.gypi +++ b/gyp/platform-osx.gypi @@ -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', ], diff --git a/gyp/standalone.gypi b/gyp/standalone.gypi new file mode 100644 index 0000000000..7f222016cd --- /dev/null +++ b/gyp/standalone.gypi @@ -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)', + ], + }, + ], +}
\ No newline at end of file diff --git a/gyp/variables.gypi b/gyp/variables.gypi deleted file mode 100644 index fd76adfb7a..0000000000 --- a/gyp/variables.gypi +++ /dev/null @@ -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', - }, - }], - ], -}
\ No newline at end of file diff --git a/include/mbgl/android/jni.hpp b/include/mbgl/android/jni.hpp index 5f71f697d0..698c024731 100644 --- a/include/mbgl/android/jni.hpp +++ b/include/mbgl/android/jni.hpp @@ -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 { diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp index c1bd085e9d..bfe544c2b0 100644 --- a/include/mbgl/android/native_map_view.hpp +++ b/include/mbgl/android/native_map_view.hpp @@ -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; diff --git a/include/mbgl/platform/platform.hpp b/include/mbgl/platform/platform.hpp index 7a6762cbcf..ea630c0956 100644 --- a/include/mbgl/platform/platform.hpp +++ b/include/mbgl/platform/platform.hpp @@ -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); diff --git a/include/mbgl/storage/asset_request_baton.hpp b/include/mbgl/storage/asset_request_baton.hpp deleted file mode 100644 index 2cbb6c51c0..0000000000 --- a/include/mbgl/storage/asset_request_baton.hpp +++ /dev/null @@ -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 diff --git a/include/mbgl/storage/default/http_context.hpp b/include/mbgl/storage/default/http_context.hpp index 18f17ef0cb..6b9518dab3 100644 --- a/include/mbgl/storage/default/http_context.hpp +++ b/include/mbgl/storage/default/http_context.hpp @@ -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()); diff --git a/include/mbgl/storage/default/request.hpp b/include/mbgl/storage/default/request.hpp index 528a49f748..81ed14a568 100644 --- a/include/mbgl/storage/default/request.hpp +++ b/include/mbgl/storage/default/request.hpp @@ -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; diff --git a/include/mbgl/storage/default/shared_request_base.hpp b/include/mbgl/storage/default/shared_request_base.hpp index 8591d66ba3..a0f3e8d4e3 100644 --- a/include/mbgl/storage/default/shared_request_base.hpp +++ b/include/mbgl/storage/default/shared_request_base.hpp @@ -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> diff --git a/include/mbgl/storage/default/thread_context.hpp b/include/mbgl/storage/default/thread_context.hpp new file mode 100644 index 0000000000..763c83a25b --- /dev/null +++ b/include/mbgl/storage/default/thread_context.hpp @@ -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 diff --git a/include/mbgl/storage/default/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp index 21048e99e5..21048e99e5 100644 --- a/include/mbgl/storage/default/default_file_source.hpp +++ b/include/mbgl/storage/default_file_source.hpp diff --git a/linux/main.cpp b/linux/main.cpp index fdcf8baab9..12f77ffe58 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -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> diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index ce066ef5e9..afcc3a83a3 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -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', ], diff --git a/macosx/main.mm b/macosx/main.mm index 5c6e67d1bd..d61d7d16bf 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -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> diff --git a/macosx/mapboxgl-app.gyp b/macosx/mapboxgl-app.gyp index 9221d7b386..37280286e5 100644 --- a/macosx/mapboxgl-app.gyp +++ b/macosx/mapboxgl-app.gyp @@ -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': [ @@ -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' ] } ], ], } diff --git a/platform/android/asset_request_libzip.cpp b/platform/android/asset_request_libzip.cpp deleted file mode 100644 index 77f9ae7da1..0000000000 --- a/platform/android/asset_request_libzip.cpp +++ /dev/null @@ -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(). -} - -} diff --git a/platform/darwin/asset_root.mm b/platform/darwin/asset_root.mm new file mode 100644 index 0000000000..375975a84b --- /dev/null +++ b/platform/darwin/asset_root.mm @@ -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; +} +} +} diff --git a/platform/darwin/http_request_cocoa.mm b/platform/darwin/http_request_nsurl.mm index efcc910488..83c010f8b8 100644 --- a/platform/darwin/http_request_cocoa.mm +++ b/platform/darwin/http_request_nsurl.mm @@ -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) { diff --git a/platform/default/asset_request_libuv.cpp b/platform/default/asset_request_fs.cpp index 4a6fc88eb6..e3875a08e8 100644 --- a/platform/default/asset_request_libuv.cpp +++ b/platform/default/asset_request_fs.cpp @@ -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); diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp new file mode 100644 index 0000000000..9c1093c5ed --- /dev/null +++ b/platform/default/asset_request_zip.cpp @@ -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; +} + +} diff --git a/platform/default/asset_root.cpp b/platform/default/asset_root.cpp new file mode 100644 index 0000000000..2b20018c40 --- /dev/null +++ b/platform/default/asset_root.cpp @@ -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; +} + +} +} diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp index 9218563ee4..411c5ee470 100644 --- a/platform/default/http_request_curl.cpp +++ b/platform/default/http_request_curl.cpp @@ -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); diff --git a/platform/default/uv_zip.c b/platform/default/uv_zip.c new file mode 100644 index 0000000000..b6d2c2ebe0 --- /dev/null +++ b/platform/default/uv_zip.c @@ -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); +} diff --git a/platform/default/uv_zip.h b/platform/default/uv_zip.h new file mode 100644 index 0000000000..5908763f09 --- /dev/null +++ b/platform/default/uv_zip.h @@ -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 diff --git a/scripts/android_env.sh b/scripts/android_env.sh new file mode 100755 index 0000000000..6cbce61dc6 --- /dev/null +++ b/scripts/android_env.sh @@ -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\"
\ No newline at end of file diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp deleted file mode 100644 index 3114d41ad2..0000000000 --- a/src/mbgl/storage/asset_request.hpp +++ /dev/null @@ -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 diff --git a/platform/default/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 60633c789e..18e21aee95 100644 --- a/platform/default/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -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> diff --git a/src/mbgl/storage/request.cpp b/src/mbgl/storage/request.cpp index 1bd58571a1..c1a57e7256 100644 --- a/src/mbgl/storage/request.cpp +++ b/src/mbgl/storage/request.cpp @@ -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); diff --git a/test/headless/headless.cpp b/test/headless/headless.cpp index cd976be27d..20f5b5b3ae 100644 --- a/test/headless/headless.cpp +++ b/test/headless/headless.cpp @@ -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> diff --git a/test/storage/cache_response.cpp b/test/storage/cache_response.cpp index 62aded7ca2..a0b5ba31c1 100644 --- a/test/storage/cache_response.cpp +++ b/test/storage/cache_response.cpp @@ -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) { diff --git a/test/storage/cache_revalidate.cpp b/test/storage/cache_revalidate.cpp index 75df5822a5..530b7325b5 100644 --- a/test/storage/cache_revalidate.cpp +++ b/test/storage/cache_revalidate.cpp @@ -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) { diff --git a/test/storage/directory_reading.cpp b/test/storage/directory_reading.cpp index 84221f3f21..bf472b5c79 100644 --- a/test/storage/directory_reading.cpp +++ b/test/storage/directory_reading.cpp @@ -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) diff --git a/test/storage/file_reading.cpp b/test/storage/file_reading.cpp index f7eea9c880..622eb2b8e8 100644 --- a/test/storage/file_reading.cpp +++ b/test/storage/file_reading.cpp @@ -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) { diff --git a/test/storage/http_cancel.cpp b/test/storage/http_cancel.cpp index 0a5194d6e0..7e485ec42d 100644 --- a/test/storage/http_cancel.cpp +++ b/test/storage/http_cancel.cpp @@ -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> diff --git a/test/storage/http_coalescing.cpp b/test/storage/http_coalescing.cpp index bfd9137ab3..592c65f8d6 100644 --- a/test/storage/http_coalescing.cpp +++ b/test/storage/http_coalescing.cpp @@ -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) diff --git a/test/storage/http_error.cpp b/test/storage/http_error.cpp index 101166780a..45c23b94b6 100644 --- a/test/storage/http_error.cpp +++ b/test/storage/http_error.cpp @@ -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> diff --git a/test/storage/http_header_parsing.cpp b/test/storage/http_header_parsing.cpp index 2cecd78a49..655348c877 100644 --- a/test/storage/http_header_parsing.cpp +++ b/test/storage/http_header_parsing.cpp @@ -2,7 +2,7 @@ #include <uv.h> -#include <mbgl/storage/default/default_file_source.hpp> +#include <mbgl/storage/default_file_source.hpp> #include <cmath> diff --git a/test/storage/http_load.cpp b/test/storage/http_load.cpp index 73057f94f4..fff662da29 100644 --- a/test/storage/http_load.cpp +++ b/test/storage/http_load.cpp @@ -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) diff --git a/test/storage/http_noloop.cpp b/test/storage/http_noloop.cpp index 673c8bf73e..c71fd0bc26 100644 --- a/test/storage/http_noloop.cpp +++ b/test/storage/http_noloop.cpp @@ -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) { diff --git a/test/storage/http_other_loop.cpp b/test/storage/http_other_loop.cpp index 45990ac217..06cc6f7476 100644 --- a/test/storage/http_other_loop.cpp +++ b/test/storage/http_other_loop.cpp @@ -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) diff --git a/test/storage/http_reading.cpp b/test/storage/http_reading.cpp index 3033a6f547..3aa57cd805 100644 --- a/test/storage/http_reading.cpp +++ b/test/storage/http_reading.cpp @@ -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) diff --git a/test/test.gyp b/test/test.gyp index c6bf4d7520..547a2d099b 100644 --- a/test/test.gyp +++ b/test/test.gyp @@ -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': [ |