diff --git a/.github/workflows/ios-ci.yml b/.github/workflows/ios-ci.yml
index 3f295a2cb..5f1c050c8 100644
--- a/.github/workflows/ios-ci.yml
+++ b/.github/workflows/ios-ci.yml
@@ -135,6 +135,8 @@ jobs:
run: make ios-uitest
# size test
+ - name: Copy example config
+ run: cp bazel/example_config.bzl bazel/config.bzl
- name: Build app for size test & output size
working-directory: ./
diff --git a/WORKSPACE b/WORKSPACE
index aee010ba2..b57779006 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -48,3 +48,12 @@ load(
)
xcodeproj_rules_dependencies()
+
+load(
+ "@build_bazel_rules_apple//apple:apple.bzl",
+ "provisioning_profile_repository",
+)
+
+provisioning_profile_repository(
+ name = "local_provisioning_profiles",
+)
diff --git a/bazel/flags.bzl b/bazel/flags.bzl
index 1a8d6f535..301e03c04 100644
--- a/bazel/flags.bzl
+++ b/bazel/flags.bzl
@@ -11,6 +11,7 @@ WARNING_FLAGS = [
"-Wno-unused-parameter",
"-Wno-unused-variable",
"-Wno-variadic-macros",
+ "-Wno-unknown-pragmas",
] + select({
"//:ios": [
"-Wno-newline-eof",
diff --git a/metrics/BUILD.bazel b/metrics/BUILD.bazel
index 42fbba6f1..d46427c1d 100644
--- a/metrics/BUILD.bazel
+++ b/metrics/BUILD.bazel
@@ -1,18 +1,26 @@
filegroup(
name = "render-test-files",
- srcs = glob([
- "cache-style.db",
+ srcs = glob(
+ [
+ "integration/**",
+ "tests/**",
+ "linux-gcc8-release/**",
+ "expectations/platform-all/**",
+ "ignores/**",
+ "ios-render-test-runner/**", # iOS only
+ "expectations/platform-ios/**", # iOS only
+ ],
+ allow_empty = False,
+ ) + [
"cache-metrics.db",
- "integration/**",
- "tests/**",
- "linux-gcc8-release/**",
- "expectations/platform-all/**",
- "ignores/**",
- ]) + [
+ "cache-style.db",
+ "ios-render-test-runner-metrics.json", # iOS only
+ "ios-render-test-runner-style.json", # iOS only
"linux-gcc8-release-metrics.json",
"linux-gcc8-release-style.json",
],
visibility = [
- "//render-test:__pkg__",
+ "//platform/ios/test/common:__pkg__",
+ "//render-test:__subpackages__",
],
)
diff --git a/platform/ios/BUILD.bazel b/platform/ios/BUILD.bazel
index 1eebed165..be9412980 100644
--- a/platform/ios/BUILD.bazel
+++ b/platform/ios/BUILD.bazel
@@ -1,13 +1,15 @@
-load("@build_bazel_rules_apple//apple:apple.bzl", "apple_static_xcframework", "apple_xcframework")
+load("@build_bazel_rules_apple//apple:apple.bzl", "apple_static_xcframework", "apple_xcframework", "local_provisioning_profile")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application", "ios_framework")
load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_bundle")
load("//bazel:flags.bzl", "CPP_FLAGS", "MAPLIBRE_FLAGS", "WARNING_FLAGS")
load(
"@rules_xcodeproj//xcodeproj:defs.bzl",
"top_level_target",
+ "xcode_provisioning_profile",
"xcodeproj",
)
load("bazel/macros.bzl", "info_plist")
+load("bazel/config.bzl", "APPLE_MOBILE_PROVISIONING_PROFILE_TEAM_ID")
# This list of public headers is from what Mapbox vendors with their dynamic framework
# If we forget one the build will fail, and if we add too many there will be a warning
@@ -460,6 +462,7 @@ ios_application(
],
infoplists = ["platform/ios/app/Info.plist"],
minimum_os_version = "12.0",
+ provisioning_profile = "xcode_profile",
resources = _IOS_APPLICATION_RESOURCES,
visibility = ["//visibility:public"],
deps = [
@@ -502,15 +505,39 @@ genrule(
""",
)
+local_provisioning_profile(
+ name = "provisioning_profile",
+ profile_name = "iOS Team Provisioning Profile: *",
+ team_id = APPLE_MOBILE_PROVISIONING_PROFILE_TEAM_ID,
+)
+
+xcode_provisioning_profile(
+ name = "xcode_profile",
+ managed_by_xcode = True,
+ provisioning_profile = ":provisioning_profile",
+ visibility = ["//visibility:public"],
+)
+
xcodeproj(
name = "xcodeproj",
+ build_mode = "xcode",
minimum_xcode_version = "14",
project_name = "MapLibre",
tags = ["manual"],
top_level_targets = [
top_level_target(
"App",
- target_environments = ["simulator"],
+ target_environments = [
+ "simulator",
+ "device",
+ ],
+ ),
+ top_level_target(
+ "//render-test/ios:RenderTest",
+ target_environments = [
+ "simulator",
+ "device",
+ ],
),
],
)
diff --git a/platform/ios/bazel/.gitignore b/platform/ios/bazel/.gitignore
new file mode 100644
index 000000000..b1053f241
--- /dev/null
+++ b/platform/ios/bazel/.gitignore
@@ -0,0 +1 @@
+/config.bzl
\ No newline at end of file
diff --git a/platform/ios/bazel/example_config.bzl b/platform/ios/bazel/example_config.bzl
new file mode 100644
index 000000000..54da9a270
--- /dev/null
+++ b/platform/ios/bazel/example_config.bzl
@@ -0,0 +1 @@
+APPLE_MOBILE_PROVISIONING_PROFILE_TEAM_ID = "TC45MCF93C"
diff --git a/platform/ios/test/common/BUILD.bazel b/platform/ios/test/common/BUILD.bazel
new file mode 100644
index 000000000..ef7df159f
--- /dev/null
+++ b/platform/ios/test/common/BUILD.bazel
@@ -0,0 +1,48 @@
+load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")
+
+cc_library(
+ name = "ios_test_runner_lib",
+ srcs = [
+ "ios_test_runner.hpp",
+ ],
+ includes = [
+ ".",
+ ],
+ visibility = [
+ "//render-test/ios:__pkg__",
+ ],
+)
+
+objc_library(
+ name = "render_test_app_srcs",
+ srcs = [
+ "AppDelegate.h",
+ "AppDelegate.m",
+ "main.m",
+ ],
+ data = [
+ "LaunchScreen.storyboard",
+ "Main.storyboard",
+ ],
+ deps = [
+ "ios_test_runner_lib",
+ ],
+)
+
+ios_application(
+ name = "RenderTestApp",
+ bundle_id = "org.maplibre.RenderTestApp",
+ families = ["iphone"],
+ infoplists = [
+ "//render-test/ios:Info.plist",
+ ],
+ minimum_os_version = "12.0",
+ provisioning_profile = "//platform/ios:xcode_profile",
+ visibility = [
+ "//visibility:public",
+ ],
+ deps = [
+ "render_test_app_srcs",
+ "//render-test/ios:render_test_ios_src",
+ ],
+)
diff --git a/platform/ios/test/common/iosTestRunner.mm b/platform/ios/test/common/iosTestRunner.mm
index b1efa74e6..67eca9d1d 100644
--- a/platform/ios/test/common/iosTestRunner.mm
+++ b/platform/ios/test/common/iosTestRunner.mm
@@ -25,6 +25,7 @@
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
+
NSArray *bundleContents = [fileManager contentsOfDirectoryAtPath: bundleRoot error: &error];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex: 0];
diff --git a/render-test/BUILD.bazel b/render-test/BUILD.bazel
index db6a967a6..2c2be3bdb 100644
--- a/render-test/BUILD.bazel
+++ b/render-test/BUILD.bazel
@@ -10,11 +10,12 @@ cc_library(
],
visibility = [
"//platform/default:__pkg__",
+ "//render-test/ios:__pkg__",
],
)
-cc_test(
- name = "render-test",
+cc_library(
+ name = "render-test-srcs",
srcs = glob(
[
"*.cpp",
@@ -23,21 +24,33 @@ cc_test(
) + [
"include/mbgl/render_test.hpp",
],
+ copts = CPP_FLAGS + MAPLIBRE_FLAGS,
+ includes = [
+ "include",
+ ],
+ visibility = [
+ "//render-test/ios:__pkg__",
+ ],
+ deps = [
+ "//expression-test:test_runner_common",
+ ] + select({
+ "//:ios": ["//platform/ios:sdk"],
+ "//:linux": ["//platform/linux:impl"],
+ }),
+)
+
+cc_test(
+ name = "render-test",
args = [
"--manifestPath",
"metrics/linux-gcc8-release-style.json",
],
- copts = CPP_FLAGS + MAPLIBRE_FLAGS,
data = [
"//metrics:render-test-files",
],
- includes = [
- "include",
- ],
deps = [
- "//expression-test:test_runner_common",
+ "render-test-srcs",
"//platform/default:render-test-bin",
- "//platform/linux:impl",
"//vendor:mapbox-base",
],
)
diff --git a/render-test/ios/BUILD.bazel b/render-test/ios/BUILD.bazel
new file mode 100644
index 000000000..18afc682f
--- /dev/null
+++ b/render-test/ios/BUILD.bazel
@@ -0,0 +1,66 @@
+load("//bazel:flags.bzl", "CPP_FLAGS", "MAPLIBRE_FLAGS")
+load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
+load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_bundle")
+
+apple_resource_bundle(
+ name = "TestData",
+ infoplists = [
+ "Empty.plist",
+ ],
+ structured_resources = [
+ "//metrics:render-test-files",
+ ],
+)
+
+objc_library(
+ name = "tests",
+ testonly = True,
+ srcs = [
+ "tests/Tests.m",
+ ],
+ deps = [
+ "render_test_ios_src",
+ ],
+)
+
+objc_library(
+ name = "render_test_ios_src",
+ srcs = [
+ "iosTestRunner.h",
+ "iosTestRunner.mm",
+ "ios_test_runner.cpp",
+ ],
+ copts = CPP_FLAGS + MAPLIBRE_FLAGS,
+ data = [
+ "TestData",
+ ],
+ includes = [
+ ".",
+ ],
+ visibility = [
+ "//platform/ios/test/common:__pkg__",
+ ],
+ deps = [
+ "//:mbgl-core",
+ "//platform/ios/test/common:ios_test_runner_lib",
+ "//render-test:render-test-lib",
+ "//render-test:render-test-srcs",
+ "//vendor:zip-archive",
+ ],
+)
+
+ios_unit_test(
+ name = "RenderTest",
+ minimum_os_version = "12.0",
+ provisioning_profile = "//platform/ios:xcode_profile",
+ runner = "@build_bazel_rules_apple//apple/testing/default_runner:ios_xctestrun_ordered_runner",
+ test_host = "//platform/ios/test/common:RenderTestApp",
+ visibility = [
+ "//visibility:public",
+ ],
+ deps = [":tests"],
+)
+
+exports_files([
+ "Info.plist",
+])
diff --git a/render-test/ios/Empty.plist b/render-test/ios/Empty.plist
new file mode 100644
index 000000000..4c8222816
--- /dev/null
+++ b/render-test/ios/Empty.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleIdentifier
+ org.maplibre.$(PRODUCT_NAME)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+
+
\ No newline at end of file
diff --git a/render-test/ios/Info.plist b/render-test/ios/Info.plist
index de3af9d72..91046744a 100644
--- a/render-test/ios/Info.plist
+++ b/render-test/ios/Info.plist
@@ -1,5 +1,5 @@
-
+
CFBundleDevelopmentRegion
@@ -9,15 +9,15 @@
CFBundleExecutable
RenderTestApp
CFBundleIdentifier
- com.mapbox.RenderTestApp
+ org.maplibre.RenderTestApp
CFBundleGetInfoString
- com.mapbox.RenderTestApp
+ org.maplibre.RenderTestApp
CFBundleInfoDictionaryVersion
1.0
CFBundleLongVersionString
1.0
CFBundleName
- com.mapbox.RenderTestApp
+ org.maplibre.RenderTestApp
CFBundlePackageType
APPL
CFBundleShortVersionString
@@ -28,10 +28,6 @@
7877
CSResourcesFileMapped
- NSHumanReadableCopyright
- © 2014–2020 Mapbox
- LSMinimumSystemVersion
- ${MACOSX_DEPLOYMENT_TARGET}
LSRequiresIPhoneOS
UILaunchStoryboardName
diff --git a/render-test/ios/iosTestRunner.mm b/render-test/ios/iosTestRunner.mm
index 4c3f7b87f..3c5dff4b0 100644
--- a/render-test/ios/iosTestRunner.mm
+++ b/render-test/ios/iosTestRunner.mm
@@ -25,117 +25,102 @@
-(instancetype)init
{
self = [super init];
- if (self) {
- self.testStatus = NO;
- self.runner = new TestRunner();
- NSString *path = nil;
- NSError *error;
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
- NSArray *bundleContents = [fileManager contentsOfDirectoryAtPath: bundleRoot error: &error];
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDir = [paths objectAtIndex: 0];
-
- for (uint32_t i = 0; i < bundleContents.count; i++) {
- NSString *dirName = [bundleContents objectAtIndex: i];
- if ([dirName isEqualToString:@"test-data"]) {
- NSString *destinationPath = [documentsDir stringByAppendingPathComponent: dirName];
- //Using NSFileManager we can perform many file system operations.
- BOOL success = [fileManager fileExistsAtPath: destinationPath];
- if (success) {
- success = [fileManager removeItemAtPath:destinationPath error:NULL];
- }
- break;
- }
+ if (!self) {
+ return nil;
+ }
+
+ self.testStatus = NO;
+ self.runner = new TestRunner();
+ NSError *error;
+ BOOL success;
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSString *xcTestBundleRoot = [[NSBundle bundleForClass:[self class]] resourcePath];
+ NSString *testDataDir = [xcTestBundleRoot stringByAppendingString:@"/TestData.bundle"];
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDir = [paths objectAtIndex: 0];
+
+ NSString *destinationPath = [documentsDir stringByAppendingPathComponent: @"test-data"];
+ NSString *path = destinationPath;
+
+ // delete destinationPath if it exists
+ if ([fileManager fileExistsAtPath:destinationPath]) {
+ success = [fileManager removeItemAtPath: destinationPath error: &error];
+ if (!success) {
+ NSAssert1(0, @"Failed to delete '%@'.", destinationPath);
}
-
- for (uint32_t i = 0; i < bundleContents.count; i++) {
- NSString *dirName = [bundleContents objectAtIndex: i];
- if ([dirName isEqualToString:@"test-data"]) {
- NSString *destinationPath = [documentsDir stringByAppendingPathComponent: dirName];
- BOOL success = [fileManager fileExistsAtPath: destinationPath];
- if (!success) {
- NSString *copyDirPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: dirName];
+ }
- success = [fileManager copyItemAtPath: copyDirPath toPath: destinationPath error: &error];
-
- if (!success){
- NSAssert1(0, @"Failed to copy file '%@'.", [error localizedDescription]);
- NSLog(@"Failed to copy %@ file, error %@", dirName, [error localizedDescription]);
- }
- else {
- path = destinationPath;
- NSLog(@"File copied %@ OK", dirName);
- }
- }
- else {
- NSLog(@"File exits %@, skip copy", dirName);
- }
- break;
- }
+ success = [fileManager copyItemAtPath: testDataDir toPath: destinationPath error: &error];
+ if (!success){
+ NSAssert1(0, @"Failed to copy file '%@'.", [error localizedDescription]);
+ NSLog(@"Failed to copy %@ file, error %@", testDataDir, [error localizedDescription]);
+ }
+ else {
+ path = destinationPath;
+ NSLog(@"File copied %@ OK", testDataDir);
+ }
+
+ if (path) {
+ std::string basePath = std::string([path UTF8String]);
+ self.testStatus = self.runner->startTest(basePath) ? YES : NO;
+ self.styleResultPath = [path stringByAppendingPathComponent:@"/ios-render-test-runner-style.html"];
+ self.metricResultPath = [path stringByAppendingPathComponent:@"/ios-render-test-runner-metrics.html"];
+
+ BOOL fileFound = [fileManager fileExistsAtPath: self.styleResultPath];
+ if (fileFound == NO) {
+ NSLog(@"Style test result file '%@' doese not exit ", self.styleResultPath);
+ self.testStatus = NO;
}
- if (path) {
- std::string basePath = std::string([path UTF8String]);
- self.testStatus = self.runner->startTest(basePath) ? YES : NO;
- self.styleResultPath = [path stringByAppendingPathComponent:@"/ios-render-test-runner-style.html"];
- self.metricResultPath = [path stringByAppendingPathComponent:@"/ios-render-test-runner-metrics.html"];
+ fileFound = [fileManager fileExistsAtPath: self.metricResultPath];
+ if (fileFound == NO) {
+ NSLog(@"Metric test result file '%@' doese not exit ", self.metricResultPath);
+ self.testStatus = NO;
+ }
- BOOL fileFound = [fileManager fileExistsAtPath: self.styleResultPath];
- if (fileFound == NO) {
- NSLog(@"Style test result file '%@' doese not exit ", self.styleResultPath);
- self.testStatus = NO;
- }
-
- fileFound = [fileManager fileExistsAtPath: self.metricResultPath];
- if (fileFound == NO) {
- NSLog(@"Metric test result file '%@' doese not exit ", self.metricResultPath);
- self.testStatus = NO;
- }
-
- NSString *rebaselinePath = [path stringByAppendingPathComponent:@"/baselines"];
- BOOL needArchiving = NO;
- BOOL isDir = NO;
- NSArray *subpaths = [[NSArray alloc] init];
- if ([fileManager fileExistsAtPath:rebaselinePath isDirectory: &isDir] && isDir){
- subpaths = [fileManager subpathsAtPath:rebaselinePath];
- for(NSString *path in subpaths)
+ NSString *rebaselinePath = [path stringByAppendingPathComponent:@"/baselines"];
+ BOOL needArchiving = NO;
+ BOOL isDir = NO;
+ NSArray *subpaths = [[NSArray alloc] init];
+ if ([fileManager fileExistsAtPath:rebaselinePath isDirectory: &isDir] && isDir){
+ subpaths = [fileManager subpathsAtPath:rebaselinePath];
+ for(NSString *path in subpaths)
+ {
+ NSString *longPath = [rebaselinePath stringByAppendingPathComponent:path];
+ if([fileManager fileExistsAtPath:longPath isDirectory:&isDir] && !isDir)
{
- NSString *longPath = [rebaselinePath stringByAppendingPathComponent:path];
- if([fileManager fileExistsAtPath:longPath isDirectory:&isDir] && !isDir)
- {
- needArchiving = YES;
- break;
- }
+ needArchiving = YES;
+ break;
}
}
+ }
+ else {
+ NSLog(@"Metric path '%@' doese not exit ", rebaselinePath);
+ }
+
+ if (needArchiving) {
+ NSString *archivePath = [path stringByAppendingString:@"/metrics.zip"];
+ BOOL success = [SSZipArchive createZipFileAtPath:archivePath
+ withContentsOfDirectory:rebaselinePath
+ keepParentDirectory:NO
+ compressionLevel:-1
+ password:nil
+ AES:YES
+ progressHandler:nil];
+
+ if (success) {
+ NSLog(@"Successfully archive all of the metrics into metrics.zip");
+ self.metricPath = archivePath;
+ }
else {
- NSLog(@"Metric path '%@' doese not exit ", rebaselinePath);
- }
-
- if (needArchiving) {
- NSString *archivePath = [path stringByAppendingString:@"/metrics.zip"];
- BOOL success = [SSZipArchive createZipFileAtPath:archivePath
- withContentsOfDirectory:rebaselinePath
- keepParentDirectory:NO
- compressionLevel:-1
- password:nil
- AES:YES
- progressHandler:nil];
-
- if (success) {
- NSLog(@"Successfully archive all of the metrics into metrics.zip");
- self.metricPath = archivePath;
- }
- else {
- NSLog(@"Failed to archive rebaselined metrics into metrics.zip");
- }
+ NSLog(@"Failed to archive rebaselined metrics into metrics.zip");
}
}
-
- delete self.runner;
- self.runner = nullptr;
}
+
+ delete self.runner;
+ self.runner = nullptr;
return self;
}
diff --git a/render-test/runner.cpp b/render-test/runner.cpp
index 2ce806079..0e9e23304 100644
--- a/render-test/runner.cpp
+++ b/render-test/runner.cpp
@@ -814,7 +814,14 @@ void TestRunner::run(TestMetadata& metadata) {
auto it = std::find_if(symbols.begin(), symbols.end(), [isIcon, box](const auto& a) {
return a.isIcon == isIcon && a.location.min == box.min && a.location.max == box.max;
});
+
+// TODO: remove usage of std::codecvt_utf8
+// https://github.com/maplibre/maplibre-native/issues/1269
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
static std::wstring_convert, char16_t> cv;
+#pragma clang diagnostic pop
+
if (it == symbols.end()) {
symbols.push_back({tileId, box, placed, isIcon});
return;
diff --git a/vendor/BUILD.bazel b/vendor/BUILD.bazel
index 53e32afc4..29e84782b 100644
--- a/vendor/BUILD.bazel
+++ b/vendor/BUILD.bazel
@@ -104,6 +104,24 @@ cc_library(
visibility = ["//visibility:public"],
)
+objc_library(
+ name = "zip-archive",
+ srcs = [
+ "zip-archive/SSZipArchive/SSZipArchive.h",
+ "zip-archive/SSZipArchive/SSZipArchive.m",
+ "zip-archive/SSZipArchive/SSZipCommon.h",
+ ] + glob(
+ [
+ "zip-archive/SSZipArchive/minizip/*.c",
+ "zip-archive/SSZipArchive/minizip/*.h",
+ ],
+ allow_empty = False,
+ ),
+ defines = ["ZLIB_COMPAT"],
+ includes = ["zip-archive/SSZipArchive"],
+ visibility = ["//visibility:public"],
+)
+
# vendor/boost-files.json
cc_library(
name = "boost",
@@ -192,6 +210,7 @@ cc_library(
hdrs = glob(["icu/include/unicode/*.h"]),
copts = CPP_FLAGS + [
"-Wno-c11-extensions",
+ "-Wno-conversion",
],
includes = ["icu/include"],
visibility = ["//visibility:public"],