Allow compiling with Rust code (#3137)
Co-authored-by: Yuri Astrakhan <YuriAstrakhan@gmail.com> Co-authored-by: Ian Wagner <ianwagner+github@switzerlandmail.ch>
This commit is contained in:
@@ -1 +1 @@
|
|||||||
7.3.1
|
8.0.0
|
||||||
|
|||||||
15
.github/workflows/linux-ci.yml
vendored
15
.github/workflows/linux-ci.yml
vendored
@@ -37,6 +37,7 @@ jobs:
|
|||||||
- name: Get all Linux files that have changed
|
- name: Get all Linux files that have changed
|
||||||
if: github.event_name != 'workflow_dispatch'
|
if: github.event_name != 'workflow_dispatch'
|
||||||
id: changed-files
|
id: changed-files
|
||||||
|
|
||||||
uses: tj-actions/changed-files@v45
|
uses: tj-actions/changed-files@v45
|
||||||
with:
|
with:
|
||||||
files_yaml_from_source_file: .github/changed-files.yml
|
files_yaml_from_source_file: .github/changed-files.yml
|
||||||
@@ -52,7 +53,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
renderer: [legacy, drawable, vulkan]
|
renderer: [legacy, drawable, vulkan, drawable-rust]
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -91,6 +92,11 @@ jobs:
|
|||||||
- if: matrix.renderer == 'drawable'
|
- if: matrix.renderer == 'drawable'
|
||||||
run: echo renderer_flag_cmake=-DMLN_DRAWABLE_RENDERER=ON >> "$GITHUB_ENV"
|
run: echo renderer_flag_cmake=-DMLN_DRAWABLE_RENDERER=ON >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- if: matrix.renderer == 'drawable-rust'
|
||||||
|
run: |
|
||||||
|
echo "renderer_flag_cmake=-DMLN_DRAWABLE_RENDERER=ON -DMLN_USE_RUST=ON" >> "$GITHUB_ENV"
|
||||||
|
cargo install cxxbridge-cmd
|
||||||
|
|
||||||
- if: matrix.renderer == 'legacy'
|
- if: matrix.renderer == 'legacy'
|
||||||
run: echo renderer_flag_cmake=-DMLN_LEGACY_RENDERER=ON >> "$GITHUB_ENV"
|
run: echo renderer_flag_cmake=-DMLN_LEGACY_RENDERER=ON >> "$GITHUB_ENV"
|
||||||
|
|
||||||
@@ -158,7 +164,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Run render test
|
- name: Run render test
|
||||||
id: render_test
|
id: render_test
|
||||||
run: xvfb-run -a build/mbgl-render-test-runner --manifestPath=metrics/linux-${{ matrix.renderer }}.json
|
run: |
|
||||||
|
renderer="${{ matrix.renderer }}"
|
||||||
|
if [[ "$renderer" == *-rust ]]; then
|
||||||
|
renderer=${renderer%-rust}
|
||||||
|
fi
|
||||||
|
xvfb-run -a build/mbgl-render-test-runner --manifestPath=metrics/linux-"$renderer".json
|
||||||
|
|
||||||
- name: Upload render test result
|
- name: Upload render test result
|
||||||
if: always() && steps.render_test.outcome == 'failure'
|
if: always() && steps.render_test.outcome == 'failure'
|
||||||
|
|||||||
@@ -24,6 +24,13 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: swiftformat
|
- id: swiftformat
|
||||||
args: [--swiftversion, "5.8"]
|
args: [--swiftversion, "5.8"]
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: rustfmt
|
||||||
|
name: rustfmt
|
||||||
|
entry: bash -c 'cd rustutils && cargo fmt' --
|
||||||
|
language: rust
|
||||||
|
types: [rust]
|
||||||
ci:
|
ci:
|
||||||
# sometimes fails https://github.com/keith/pre-commit-buildifier/issues/13
|
# sometimes fails https://github.com/keith/pre-commit-buildifier/issues/13
|
||||||
skip: [buildifier]
|
skip: [buildifier]
|
||||||
|
|||||||
23
BUILD.bazel
23
BUILD.bazel
@@ -1,5 +1,5 @@
|
|||||||
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_library", "js_run_binary")
|
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_library", "js_run_binary")
|
||||||
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
|
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")
|
||||||
load("@npm//:defs.bzl", "npm_link_all_packages")
|
load("@npm//:defs.bzl", "npm_link_all_packages")
|
||||||
load(
|
load(
|
||||||
"//bazel:core.bzl",
|
"//bazel:core.bzl",
|
||||||
@@ -124,7 +124,6 @@ cc_library(
|
|||||||
":mbgl-core-generated-private-artifacts",
|
":mbgl-core-generated-private-artifacts",
|
||||||
":mbgl-core-generated-public-artifacts",
|
":mbgl-core-generated-public-artifacts",
|
||||||
"//vendor:boost",
|
"//vendor:boost",
|
||||||
"//vendor:csscolorparser",
|
|
||||||
"//vendor:earcut.hpp",
|
"//vendor:earcut.hpp",
|
||||||
"//vendor:eternal",
|
"//vendor:eternal",
|
||||||
"//vendor:mapbox-base",
|
"//vendor:mapbox-base",
|
||||||
@@ -149,6 +148,13 @@ cc_library(
|
|||||||
"//vendor:metal-cpp",
|
"//vendor:metal-cpp",
|
||||||
],
|
],
|
||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
|
}) + select({
|
||||||
|
":rust": [
|
||||||
|
"//rustutils:rustutilslib",
|
||||||
|
],
|
||||||
|
"//conditions:default": [
|
||||||
|
"//vendor:csscolorparser",
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -195,6 +201,19 @@ config_setting(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bool_flag(
|
||||||
|
name = "use_rust",
|
||||||
|
build_setting_default = False,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "rust",
|
||||||
|
flag_values = {
|
||||||
|
"//:use_rust": "true",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
exports_files(
|
exports_files(
|
||||||
[
|
[
|
||||||
"LICENSE.md",
|
"LICENSE.md",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ option(MLN_LEGACY_RENDERER "Include the legacy rendering pathway" ON)
|
|||||||
option(MLN_DRAWABLE_RENDERER "Include the drawable rendering pathway" OFF)
|
option(MLN_DRAWABLE_RENDERER "Include the drawable rendering pathway" OFF)
|
||||||
option(MLN_USE_UNORDERED_DENSE "Use ankerl dense containers for performance" ON)
|
option(MLN_USE_UNORDERED_DENSE "Use ankerl dense containers for performance" ON)
|
||||||
option(MLN_USE_TRACY "Enable Tracy instrumentation" OFF)
|
option(MLN_USE_TRACY "Enable Tracy instrumentation" OFF)
|
||||||
|
option(MLN_USE_RUST "Use components in Rust" OFF)
|
||||||
|
|
||||||
if (MLN_WITH_CLANG_TIDY)
|
if (MLN_WITH_CLANG_TIDY)
|
||||||
find_program(CLANG_TIDY_COMMAND NAMES clang-tidy)
|
find_program(CLANG_TIDY_COMMAND NAMES clang-tidy)
|
||||||
@@ -940,7 +941,7 @@ list(APPEND SRC_FILES
|
|||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/bounding_volumes.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/bounding_volumes.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/chrono.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/chrono.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/client_options.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/client_options.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/color.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/color$<IF:$<BOOL:${MLN_USE_RUST}>,.rs.cpp,.cpp>
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/constants.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/constants.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/convert.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/convert.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/event.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/event.cpp
|
||||||
@@ -1458,6 +1459,10 @@ include(${PROJECT_SOURCE_DIR}/vendor/vector-tile.cmake)
|
|||||||
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.cmake)
|
||||||
|
|
||||||
|
if(MLN_USE_RUST)
|
||||||
|
include(${PROJECT_SOURCE_DIR}/rustutils/rustutils.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
mbgl-core
|
mbgl-core
|
||||||
PRIVATE
|
PRIVATE
|
||||||
@@ -1468,7 +1473,6 @@ target_link_libraries(
|
|||||||
Mapbox::Base::cheap-ruler-cpp
|
Mapbox::Base::cheap-ruler-cpp
|
||||||
mbgl-compiler-options
|
mbgl-compiler-options
|
||||||
mbgl-vendor-boost
|
mbgl-vendor-boost
|
||||||
mbgl-vendor-csscolorparser
|
|
||||||
mbgl-vendor-earcut.hpp
|
mbgl-vendor-earcut.hpp
|
||||||
mbgl-vendor-eternal
|
mbgl-vendor-eternal
|
||||||
mbgl-vendor-parsedate
|
mbgl-vendor-parsedate
|
||||||
@@ -1479,6 +1483,7 @@ target_link_libraries(
|
|||||||
mbgl-vendor-vector-tile
|
mbgl-vendor-vector-tile
|
||||||
mbgl-vendor-wagyu
|
mbgl-vendor-wagyu
|
||||||
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
|
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
|
||||||
|
$<IF:$<BOOL:${MLN_USE_RUST}>,mbgl-rustutils,mbgl-vendor-csscolorparser>
|
||||||
PUBLIC
|
PUBLIC
|
||||||
Mapbox::Base
|
Mapbox::Base
|
||||||
Mapbox::Base::Extras::expected-lite
|
Mapbox::Base::Extras::expected-lite
|
||||||
@@ -1490,9 +1495,8 @@ target_link_libraries(
|
|||||||
unordered_dense
|
unordered_dense
|
||||||
)
|
)
|
||||||
|
|
||||||
export(TARGETS
|
set(EXPORT_TARGETS
|
||||||
mbgl-core
|
mbgl-core
|
||||||
|
|
||||||
mapbox-base
|
mapbox-base
|
||||||
mapbox-base-cheap-ruler-cpp
|
mapbox-base-cheap-ruler-cpp
|
||||||
mapbox-base-extras-expected-lite
|
mapbox-base-extras-expected-lite
|
||||||
@@ -1508,7 +1512,6 @@ export(TARGETS
|
|||||||
mapbox-base-variant
|
mapbox-base-variant
|
||||||
mbgl-compiler-options
|
mbgl-compiler-options
|
||||||
mbgl-vendor-boost
|
mbgl-vendor-boost
|
||||||
mbgl-vendor-csscolorparser
|
|
||||||
mbgl-vendor-earcut.hpp
|
mbgl-vendor-earcut.hpp
|
||||||
mbgl-vendor-eternal
|
mbgl-vendor-eternal
|
||||||
mbgl-vendor-parsedate
|
mbgl-vendor-parsedate
|
||||||
@@ -1520,10 +1523,16 @@ export(TARGETS
|
|||||||
mbgl-vendor-wagyu
|
mbgl-vendor-wagyu
|
||||||
mbgl-vendor-metal-cpp
|
mbgl-vendor-metal-cpp
|
||||||
unordered_dense
|
unordered_dense
|
||||||
|
|
||||||
FILE MapboxCoreTargets.cmake
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MLN_USE_RUST)
|
||||||
|
list(APPEND EXPORT_TARGETS mbgl-rustutils rustutils)
|
||||||
|
else()
|
||||||
|
list(APPEND EXPORT_TARGETS mbgl-vendor-csscolorparser)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
export(TARGETS ${EXPORT_TARGETS} FILE MapboxCoreTargets.cmake)
|
||||||
|
|
||||||
if(MLN_WITH_VULKAN)
|
if(MLN_WITH_VULKAN)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/vulkan.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/vulkan.cmake)
|
||||||
|
|
||||||
|
|||||||
35
MODULE.bazel
35
MODULE.bazel
@@ -1,6 +1,6 @@
|
|||||||
module(name = "maplibre")
|
module(name = "maplibre")
|
||||||
|
|
||||||
bazel_dep(name = "apple_support", version = "1.17.0", repo_name = "build_bazel_apple_support")
|
bazel_dep(name = "apple_support", version = "1.17.1", repo_name = "build_bazel_apple_support")
|
||||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||||
bazel_dep(name = "platforms", version = "0.0.10")
|
bazel_dep(name = "platforms", version = "0.0.10")
|
||||||
bazel_dep(name = "rules_apple", version = "3.16.1", repo_name = "build_bazel_rules_apple")
|
bazel_dep(name = "rules_apple", version = "3.16.1", repo_name = "build_bazel_rules_apple")
|
||||||
@@ -59,4 +59,35 @@ darwin_config = use_repo_rule("//platform/darwin:bazel/darwin_config_repository_
|
|||||||
|
|
||||||
darwin_config(
|
darwin_config(
|
||||||
name = "darwin_config",
|
name = "darwin_config",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bazel_dep(name = "rules_rust", version = "0.56.0")
|
||||||
|
bazel_dep(name = "cxx.rs", version = "1.0.136")
|
||||||
|
git_override(
|
||||||
|
module_name = "cxx.rs",
|
||||||
|
commit = "d54e44698c3fa5833a861cb3ae502533b92f2f57",
|
||||||
|
remote = "https://github.com/dtolnay/cxx.git",
|
||||||
|
)
|
||||||
|
|
||||||
|
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||||
|
rust.toolchain(
|
||||||
|
edition = "2021",
|
||||||
|
extra_target_triples = [
|
||||||
|
"aarch64-apple-ios-sim",
|
||||||
|
"x86_64-apple-ios",
|
||||||
|
"aarch64-apple-ios",
|
||||||
|
"aarch64-apple-darwin",
|
||||||
|
"x86_64-apple-darwin",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
use_repo(rust, "rust_toolchains")
|
||||||
|
|
||||||
|
register_toolchains("@rust_toolchains//:all")
|
||||||
|
|
||||||
|
crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
|
||||||
|
crate.from_cargo(
|
||||||
|
name = "crates",
|
||||||
|
cargo_lockfile = "//rustutils:Cargo.lock",
|
||||||
|
manifests = ["//rustutils:Cargo.toml"],
|
||||||
|
)
|
||||||
|
use_repo(crate, "crates")
|
||||||
|
|||||||
@@ -584,7 +584,6 @@ MLN_CORE_SOURCE = [
|
|||||||
"src/mbgl/util/bounding_volumes.cpp",
|
"src/mbgl/util/bounding_volumes.cpp",
|
||||||
"src/mbgl/util/chrono.cpp",
|
"src/mbgl/util/chrono.cpp",
|
||||||
"src/mbgl/util/client_options.cpp",
|
"src/mbgl/util/client_options.cpp",
|
||||||
"src/mbgl/util/color.cpp",
|
|
||||||
"src/mbgl/util/constants.cpp",
|
"src/mbgl/util/constants.cpp",
|
||||||
"src/mbgl/util/convert.cpp",
|
"src/mbgl/util/convert.cpp",
|
||||||
"src/mbgl/util/event.cpp",
|
"src/mbgl/util/event.cpp",
|
||||||
@@ -652,7 +651,14 @@ MLN_CORE_SOURCE = [
|
|||||||
"src/mbgl/util/version.cpp",
|
"src/mbgl/util/version.cpp",
|
||||||
"src/mbgl/util/version.hpp",
|
"src/mbgl/util/version.hpp",
|
||||||
"src/mbgl/util/work_request.cpp",
|
"src/mbgl/util/work_request.cpp",
|
||||||
]
|
] + select({
|
||||||
|
"//:rust": [
|
||||||
|
"src/mbgl/util/color.rs.cpp",
|
||||||
|
],
|
||||||
|
"//conditions:default": [
|
||||||
|
"src/mbgl/util/color.cpp",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
MLN_CORE_HEADERS = [
|
MLN_CORE_HEADERS = [
|
||||||
"include/mbgl/gfx/context.hpp",
|
"include/mbgl/gfx/context.hpp",
|
||||||
|
|||||||
@@ -23,12 +23,16 @@ RUN apt-get update \
|
|||||||
ccache \
|
ccache \
|
||||||
ninja-build \
|
ninja-build \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
python-is-python3 \
|
||||||
clang-tidy \
|
clang-tidy \
|
||||||
&& : # end of the RUN cmd - easier to keep a colon at the end of the list, than to keep the backslashes in check
|
&& : # end of the RUN cmd - easier to keep a colon at the end of the list, than to keep the backslashes in check
|
||||||
|
|
||||||
# This could also be `.../releases/latest/download/bazelisk-linux-amd64` for the latest version, but for predictability better hardcode it
|
# This could also be `.../releases/latest/download/bazelisk-linux-amd64` for the latest version, but for predictability better hardcode it
|
||||||
# Detect if current CPU is x64 or ARM64 and download the appropriate binary
|
# Detect if current CPU is x64 or ARM64 and download the appropriate binary
|
||||||
RUN if [ "$(uname -m)" = "aarch64" ]; then \
|
RUN echo "Download and install Bazel" \
|
||||||
|
&& if [ "$(uname -m)" = "aarch64" ]; then \
|
||||||
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-arm64 -o /usr/local/bin/bazel ;\
|
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-arm64 -o /usr/local/bin/bazel ;\
|
||||||
else \
|
else \
|
||||||
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-amd64 -o /usr/local/bin/bazel ;\
|
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-amd64 -o /usr/local/bin/bazel ;\
|
||||||
@@ -36,7 +40,6 @@ RUN if [ "$(uname -m)" = "aarch64" ]; then \
|
|||||||
&& chmod +x /usr/local/bin/bazel \
|
&& chmod +x /usr/local/bin/bazel \
|
||||||
&& :
|
&& :
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
ARG USERNAME=user
|
ARG USERNAME=user
|
||||||
ARG USER_UID=1000
|
ARG USER_UID=1000
|
||||||
@@ -50,11 +53,21 @@ RUN groupadd --force --gid $USER_GID $USERNAME \
|
|||||||
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
|
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
|
||||||
&& chmod 0440 /etc/sudoers.d/$USERNAME
|
&& chmod 0440 /etc/sudoers.d/$USERNAME
|
||||||
|
|
||||||
COPY startup.sh /usr/local/bin/startup.sh
|
|
||||||
RUN chmod +x /usr/local/bin/startup.sh
|
|
||||||
|
|
||||||
# This allows users to `docker run` without specifying -u and -g
|
# This allows users to `docker run` without specifying -u and -g
|
||||||
USER $USERNAME
|
USER $USERNAME
|
||||||
|
|
||||||
|
RUN pip install pre-commit
|
||||||
|
|
||||||
|
ENV RUSTUP_HOME=/home/$USERNAME/.cache/.rustup \
|
||||||
|
CARGO_HOME=/home/$USERNAME/.cache/.cargo \
|
||||||
|
PATH=/home/$USERNAME/.cache/.cargo/bin:$PATH
|
||||||
|
|
||||||
|
# As the very last step, copy the startup script
|
||||||
|
USER root
|
||||||
|
COPY startup.sh /usr/local/bin/startup.sh
|
||||||
|
RUN chmod +x /usr/local/bin/startup.sh
|
||||||
|
USER $USERNAME
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
ENTRYPOINT ["/usr/local/bin/startup.sh"]
|
ENTRYPOINT ["/usr/local/bin/startup.sh"]
|
||||||
CMD ["bash"]
|
CMD ["bash"]
|
||||||
|
|||||||
@@ -1,13 +1,51 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ ! -d /app/.github ] || [ ! -d /home/user/.cache ]; then
|
if [ ! -d /app/.github ] || [ ! -d ~/.cache ]; then
|
||||||
echo " "
|
echo " "
|
||||||
echo "ERROR: Docker container was not started properly."
|
echo "ERROR: Docker container was not started properly."
|
||||||
echo " From the root of this repo, run the following command."
|
echo " From the root of this repo, run the following command."
|
||||||
echo " You may add any command to perform in the container at the end of this command."
|
echo " You may add any command to perform in the container at the end of this command."
|
||||||
echo " "
|
echo " "
|
||||||
echo ' docker run --rm -it -v "$PWD:/app/" -v "$PWD/docker/.cache:/home/user/.cache" maplibre-native-image'
|
echo ' docker run --rm -it -v "$PWD:/app/" -v "$PWD/docker/.cache:/home/'"$USERNAME"'/.cache" maplibre-native-image'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export PATH="$PATH:~/.local/bin/"
|
||||||
|
|
||||||
|
|
||||||
|
# Work in progress: install and configure Swift and pre-commit
|
||||||
|
# Detect if current CPU is x64 or ARM64 and download the appropriate binary
|
||||||
|
#RUN echo "Download and install SWIFT" \
|
||||||
|
# && if [ "$(uname -m)" = "aarch64" ]; then \
|
||||||
|
# curl -fsSL https://download.swift.org/swift-5.10.1-release/ubuntu2204-aarch64/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-ubuntu22.04-aarch64.tar.gz \
|
||||||
|
# -o /tmp/swift.tar.gz ;\
|
||||||
|
# else \
|
||||||
|
# curl -fsSL https://download.swift.org/swift-5.10.1-release/ubuntu2204/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-ubuntu22.04.tar.gz \
|
||||||
|
# -o /tmp/swift.tar.gz ;\
|
||||||
|
# fi \
|
||||||
|
# && tar -xzf /tmp/swift.tar.gz -C / --strip-components=1 \
|
||||||
|
# && rm /tmp/swift.tar.gz \
|
||||||
|
# && :
|
||||||
|
#if [ ! -f "/app/.git/hooks/pre-commit" ]; then
|
||||||
|
# echo "Configuring pre-commit git hooks by creating a .git/hooks/pre-commit file..."
|
||||||
|
# ~/.local/bin/pre-commit install
|
||||||
|
#fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ ! -f "$CARGO_HOME/env" ]; then
|
||||||
|
echo "Downloading and installing Rust..."
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
||||||
|
fi
|
||||||
|
. "$CARGO_HOME/env"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ! command -v cxxbridge > /dev/null; then
|
||||||
|
echo "Installing cxxbridge..."
|
||||||
|
cargo install cxxbridge-cmd
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -22,3 +22,5 @@
|
|||||||
|
|
||||||
- [Profiling applications that use MapLibre Native](./profiling/README.md)
|
- [Profiling applications that use MapLibre Native](./profiling/README.md)
|
||||||
- [Tracy profiling](./profiling/tracy-profiling.md)
|
- [Tracy profiling](./profiling/tracy-profiling.md)
|
||||||
|
|
||||||
|
- [Rust](./rust.md)
|
||||||
|
|||||||
67
docs/mdbook/src/rust.md
Normal file
67
docs/mdbook/src/rust.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# Rust
|
||||||
|
|
||||||
|
We have added experimental support for intergrating Rust code into the source tree.
|
||||||
|
|
||||||
|
## Rust Bridge
|
||||||
|
|
||||||
|
The Rust bridge lives in the root `rustutils` directory.
|
||||||
|
|
||||||
|
We use [CXX](https://cxx.rs/) to allow interop between Rust and C++.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
### CMake
|
||||||
|
|
||||||
|
When building with CMake, need to have the correct Rust toolchain(s) installed. See [Install Rust](https://www.rust-lang.org/tools/install) to install Rust.
|
||||||
|
|
||||||
|
You can use `rustup` to manage toolchains. Which toolchain you needs depends on your host platform and for what platform you are trying to build. If your host and target platform are the same, you probably have the correct toolchain installed after installing Rust. For example when building for **Android** and building on a **x84 Linux** host you would use the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
rustup target add --toolchain stable-x86_64-unknown-linux-gnu aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Platform Support](https://doc.rust-lang.org/nightly/rustc/platform-support.html) in the Rust documentation for more details. You will get a descriptive error message when the correct toolchain is not available, so we don't list all possible combinations here.
|
||||||
|
|
||||||
|
You also need to have cxxbridge installed:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo install cxxbridge-cmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Set `-DMLN_USE_RUST=ON` when generating a configuration with CMake.
|
||||||
|
|
||||||
|
### Bazel
|
||||||
|
|
||||||
|
Pass the `--//:use_rust` flag to Bazel commands.
|
||||||
|
|
||||||
|
Note that when [generating an Xcode project](./ios/README.md) you should not pass this option to Bazel directly, but as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
bazel run //platform/ios:xcodeproj --@rules_xcodeproj//xcodeproj:extra_common_flags="--//:renderer=metal --//:use_rust"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating a new Module
|
||||||
|
|
||||||
|
To create a new module:
|
||||||
|
|
||||||
|
1. Add a new source file to `rustutils/src/example.rs`.
|
||||||
|
2. Implement it, see the [CXX documentation](https://cxx.rs/index.html) or see `rustutils/src/color.rs` for an example.
|
||||||
|
3. Create a C++ source file that will use the generated C++ header. See `src/mbgl/util/color.rs.cpp` for an example. Import the generated header with
|
||||||
|
```
|
||||||
|
#include <rustutils/example.hpp>
|
||||||
|
```
|
||||||
|
4. Conditionally include either the `*.rs.cpp` file or the `*.cpp` file it replaces in CMake and Bazel. Here is what it looks like for CMake:
|
||||||
|
```
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/color$<IF:$<BOOL:${MLN_USE_RUST}>,.rs.cpp,.cpp>
|
||||||
|
```
|
||||||
|
And here for Bazel:
|
||||||
|
```
|
||||||
|
select({
|
||||||
|
"//:rust": [
|
||||||
|
"src/mbgl/util/color.rs.cpp",
|
||||||
|
],
|
||||||
|
"//conditions:default": [
|
||||||
|
"src/mbgl/util/color.cpp",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
```
|
||||||
1
rustutils/.gitignore
vendored
Normal file
1
rustutils/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
46
rustutils/BUILD.bazel
Normal file
46
rustutils/BUILD.bazel
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
load("@rules_rust//rust:defs.bzl", "rust_static_library")
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "cpp_bindings",
|
||||||
|
srcs = [
|
||||||
|
"src/color.rs",
|
||||||
|
],
|
||||||
|
outs = [
|
||||||
|
"cpp/include/rustutils/color.hpp",
|
||||||
|
"cpp/src/color.rs.cpp",
|
||||||
|
],
|
||||||
|
cmd = "CXXBRIDGE_CMD=$(location @cxx.rs//:codegen) ./$(location :generate.sh) $(@D) $(SRCS)",
|
||||||
|
# Using the cxxbridge binary built by Bazel
|
||||||
|
tools = [
|
||||||
|
":generate.sh",
|
||||||
|
"@cxx.rs//:codegen",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rust_static_library(
|
||||||
|
name = "rustutils",
|
||||||
|
srcs = [
|
||||||
|
"src/color.rs",
|
||||||
|
"src/lib.rs",
|
||||||
|
],
|
||||||
|
crate_name = "rustutils",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"@crates//:csscolorparser",
|
||||||
|
"@crates//:cxx",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "rustutilslib",
|
||||||
|
srcs = [
|
||||||
|
":cpp_bindings",
|
||||||
|
],
|
||||||
|
includes = [
|
||||||
|
"cpp/include",
|
||||||
|
],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
":rustutils",
|
||||||
|
],
|
||||||
|
)
|
||||||
162
rustutils/Cargo.lock
generated
Normal file
162
rustutils/Cargo.lock
generated
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csscolorparser"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
|
||||||
|
dependencies = [
|
||||||
|
"phf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxx"
|
||||||
|
version = "1.0.124"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cxxbridge-flags",
|
||||||
|
"cxxbridge-macro",
|
||||||
|
"link-cplusplus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxxbridge-flags"
|
||||||
|
version = "1.0.124"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxxbridge-macro"
|
||||||
|
version = "1.0.124"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "link-cplusplus"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustutils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"csscolorparser",
|
||||||
|
"cxx",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
19
rustutils/Cargo.toml
Normal file
19
rustutils/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "rustutils"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["MapLibre contributors"]
|
||||||
|
description = "Core Rust utilities for MapLibre Native"
|
||||||
|
edition = "2021"
|
||||||
|
license = "BSD-2-Clause"
|
||||||
|
repository = "https://github.com/maplibre/maplibre-native"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
csscolorparser = "0.6.2"
|
||||||
|
cxx = "1"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
35
rustutils/generate.sh
Executable file
35
rustutils/generate.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run this script from the repository root
|
||||||
|
# Install cxxbridge with:
|
||||||
|
# $ cargo install cxxbridge-cmd
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
echo "Error: output_dir and at least one input file are required." >&2
|
||||||
|
echo "Usage: $0 <output_dir> <input_file1> [input_file2 ...]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use CXXBRIDGE_CMD environment variable if set, otherwise fallback to "cxxbridge"
|
||||||
|
CXXBRIDGE_CMD="${CXXBRIDGE_CMD:-cxxbridge}"
|
||||||
|
|
||||||
|
output_dir="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
for input_file in "$@"; do
|
||||||
|
if [[ "$input_file" != *.rs ]]; then
|
||||||
|
echo "Error: All input files must have a .rs extension. Invalid file: $input_file" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "$output_dir/cpp/include/rustutils"
|
||||||
|
mkdir -p "$output_dir/cpp/src"
|
||||||
|
|
||||||
|
for input_file in "$@"; do
|
||||||
|
base_name=$(basename "$input_file" .rs)
|
||||||
|
"$CXXBRIDGE_CMD" "$input_file" --header > "$output_dir/cpp/include/rustutils/${base_name}.hpp"
|
||||||
|
"$CXXBRIDGE_CMD" "$input_file" > "$output_dir/cpp/src/${base_name}.rs.cpp"
|
||||||
|
done
|
||||||
63
rustutils/rustutils.cmake
Normal file
63
rustutils/rustutils.cmake
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Include guard
|
||||||
|
if(TARGET rustutils)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
Corrosion
|
||||||
|
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||||
|
GIT_TAG v0.5 # Optionally specify a commit hash, version tag or branch here
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(Corrosion)
|
||||||
|
|
||||||
|
corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_LIST_DIR}/Cargo.toml)
|
||||||
|
|
||||||
|
# Define output directories for generated bindings
|
||||||
|
set(RUSTUTILS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/rustutils_bindings")
|
||||||
|
set(RUSTUTILS_INCLUDE_DIR "${RUSTUTILS_OUTPUT_DIR}/cpp/include")
|
||||||
|
set(RUSTUTILS_SRC_DIR "${RUSTUTILS_OUTPUT_DIR}/cpp/src")
|
||||||
|
|
||||||
|
# Ensure the output directories exist
|
||||||
|
file(MAKE_DIRECTORY ${RUSTUTILS_INCLUDE_DIR})
|
||||||
|
file(MAKE_DIRECTORY ${RUSTUTILS_SRC_DIR})
|
||||||
|
|
||||||
|
set(RUSTUTILS_RS_FILES
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/color.rs
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize variables for generated files
|
||||||
|
set(RUSTUTILS_GENERATED_SOURCES)
|
||||||
|
set(RUSTUTILS_GENERATED_HEADERS)
|
||||||
|
|
||||||
|
# Transform .rs to .rs.cpp and .hpp
|
||||||
|
foreach(rs_file ${RUSTUTILS_RS_FILES})
|
||||||
|
get_filename_component(base_name ${rs_file} NAME_WE)
|
||||||
|
list(APPEND RUSTUTILS_GENERATED_SOURCES "${RUSTUTILS_SRC_DIR}/${base_name}.rs.cpp")
|
||||||
|
list(APPEND RUSTUTILS_GENERATED_HEADERS "${RUSTUTILS_INCLUDE_DIR}/rustutils/${base_name}.hpp")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${RUSTUTILS_GENERATED_SOURCES} ${RUSTUTILS_GENERATED_HEADERS}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/generate.sh ${RUSTUTILS_OUTPUT_DIR} ${RUSTUTILS_RS_FILES}
|
||||||
|
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/generate.sh ${RUSTUTILS_RS_FILES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
COMMENT "Generating C++ bindings for Rust sources"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(rustutils_bindings DEPENDS ${RUSTUTILS_GENERATED_SOURCES} ${RUSTUTILS_GENERATED_HEADERS})
|
||||||
|
|
||||||
|
add_library(mbgl-rustutils STATIC
|
||||||
|
${RUSTUTILS_GENERATED_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(mbgl-rustutils rustutils_bindings)
|
||||||
|
|
||||||
|
target_include_directories(mbgl-rustutils PUBLIC
|
||||||
|
${RUSTUTILS_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(mbgl-rustutils PUBLIC rustutils)
|
||||||
35
rustutils/src/color.rs
Normal file
35
rustutils/src/color.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use csscolorparser::Color;
|
||||||
|
|
||||||
|
#[cxx::bridge(namespace = "rustutils")]
|
||||||
|
mod ffi {
|
||||||
|
struct ParsedColor {
|
||||||
|
pub success: bool,
|
||||||
|
pub r: f32,
|
||||||
|
pub g: f32,
|
||||||
|
pub b: f32,
|
||||||
|
pub a: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
fn parse_css_color(css_str: &str) -> ParsedColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_css_color(css_str: &str) -> ffi::ParsedColor {
|
||||||
|
css_str
|
||||||
|
.parse::<Color>()
|
||||||
|
.map(|color| ffi::ParsedColor {
|
||||||
|
success: true,
|
||||||
|
r: color.r as f32,
|
||||||
|
g: color.g as f32,
|
||||||
|
b: color.b as f32,
|
||||||
|
a: color.a as f32,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|_| ffi::ParsedColor {
|
||||||
|
success: false,
|
||||||
|
r: 0.0,
|
||||||
|
g: 0.0,
|
||||||
|
b: 0.0,
|
||||||
|
a: 0.0,
|
||||||
|
})
|
||||||
|
}
|
||||||
1
rustutils/src/lib.rs
Normal file
1
rustutils/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
mod color;
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
function(mbgl_generate_license param)
|
function(mbgl_generate_license param)
|
||||||
# Fake targets or non relevant.
|
# Fake targets or non relevant.
|
||||||
set(BLACKLIST "mbgl-compiler-options")
|
set(BLACKLIST "mbgl-compiler-options" "mbgl-rustutils")
|
||||||
|
|
||||||
get_target_property(LIBRARIES ${param} LINK_LIBRARIES)
|
get_target_property(LIBRARIES ${param} LINK_LIBRARIES)
|
||||||
list(INSERT LIBRARIES 0 ${param})
|
list(INSERT LIBRARIES 0 ${param})
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
std::optional<Color> Color::parse(const std::string& s) {
|
std::optional<Color> Color::parse(const std::string& s) {
|
||||||
auto css_color = CSSColorParser::parse(s);
|
const auto css_color = CSSColorParser::parse(s);
|
||||||
|
|
||||||
// Premultiply the color.
|
// Premultiply the color.
|
||||||
if (css_color) {
|
if (css_color) {
|
||||||
|
|||||||
58
src/mbgl/util/color.rs.cpp
Normal file
58
src/mbgl/util/color.rs.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// This is an interface-compatible file analogous to color.cpp
|
||||||
|
// which is conditionally compiled when the optional Rust build flag is enabled.
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <mbgl/util/color.hpp>
|
||||||
|
#include <mbgl/util/string.hpp>
|
||||||
|
|
||||||
|
#include <rustutils/color.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
std::optional<Color> Color::parse(const std::string& s) {
|
||||||
|
const auto css_color = rustutils::parse_css_color(s);
|
||||||
|
if (css_color.success) {
|
||||||
|
return {{css_color.r * css_color.a, css_color.g * css_color.a, css_color.b * css_color.a, css_color.a}};
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Color::stringify() const {
|
||||||
|
std::array<double, 4> array = toArray();
|
||||||
|
return "rgba(" + util::toString(array[0]) + "," + util::toString(array[1]) + "," + util::toString(array[2]) + "," +
|
||||||
|
util::toString(array[3]) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<double, 4> Color::toArray() const {
|
||||||
|
if (a == 0) {
|
||||||
|
return {{0, 0, 0, 0}};
|
||||||
|
} else {
|
||||||
|
return {{
|
||||||
|
r * 255 / a,
|
||||||
|
g * 255 / a,
|
||||||
|
b * 255 / a,
|
||||||
|
floor(a * 100 + .5) / 100 // round to 2 decimal places
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mbgl::Value Color::toObject() const {
|
||||||
|
return mapbox::base::ValueObject{{"r", static_cast<double>(r)},
|
||||||
|
{"g", static_cast<double>(g)},
|
||||||
|
{"b", static_cast<double>(b)},
|
||||||
|
{"a", static_cast<double>(a)}};
|
||||||
|
}
|
||||||
|
|
||||||
|
mbgl::Value Color::serialize() const {
|
||||||
|
std::array<double, 4> array = toArray();
|
||||||
|
return std::vector<mbgl::Value>{
|
||||||
|
std::string("rgba"),
|
||||||
|
array[0],
|
||||||
|
array[1],
|
||||||
|
array[2],
|
||||||
|
array[3],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
@@ -25,6 +25,7 @@ const std::map<std::string, std::optional<Color>> testCases = {
|
|||||||
{"#123", Color(0.067f, 0.133f, 0.2f, 1.0f)}, // Short hex format
|
{"#123", Color(0.067f, 0.133f, 0.2f, 1.0f)}, // Short hex format
|
||||||
{"rgb(-10, 0, 0)", Color(0.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 0
|
{"rgb(-10, 0, 0)", Color(0.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 0
|
||||||
{"rgba(300, 0, 0, 1.0)", Color(1.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 1
|
{"rgba(300, 0, 0, 1.0)", Color(1.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 1
|
||||||
|
{"rgba(100,100,100,0.2)", Color(20.0f / 255, 20.0f / 255, 20.0f / 255, 0.2f)},
|
||||||
// {"#GGGGGG", Color(0.0f, 0.0f, 0.0f, 1.0f)}, // Treated as fallback black
|
// {"#GGGGGG", Color(0.0f, 0.0f, 0.0f, 1.0f)}, // Treated as fallback black
|
||||||
// not supported right now
|
// not supported right now
|
||||||
// {"#0F0F", Color(0.0f, 1.0f, 0.0f, 1.0f)},
|
// {"#0F0F", Color(0.0f, 1.0f, 0.0f, 1.0f)},
|
||||||
|
|||||||
Reference in New Issue
Block a user