Compare commits

..

1 Commits

Author SHA1 Message Date
Andrea Giudiceandrea
1eab67f03c
Merge 488856c04e2eba4b35f5c3d609418364cf76f1cc into 1637be8a37d620fdd032b9a0df9ba9bc8f2fc7d1 2025-06-23 16:46:01 +02:00
749 changed files with 7382 additions and 13034 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,2 @@
*.sip export-subst
*.py export-subst
tests/testdata/auth_system/certs_keys/donald_key_DSA_crlf.pem text eol=crlf

View File

@ -1,34 +0,0 @@
name: 'Get Workflow Artifact IDs'
description: 'Generates consistent artifact IDs and names based on workflow trigger'
outputs:
filename:
description: 'Filename to use for artifacts (e.g. pr123)'
value: ${{ steps.generate-ids.outputs.filename }}
display-name:
description: 'Human readable name (e.g. PR123)'
value: ${{ steps.generate-ids.outputs.display_name }}
runs:
using: "composite"
steps:
- id: generate-ids
shell: bash
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
ID="pr${{ github.event.pull_request.number }}"
DISPLAY_ID="PR${{ github.event.pull_request.number }}"
elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
TAG=${GITHUB_REF#refs/tags/}
ID="$TAG"
DISPLAY_ID="$TAG"
else
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
BRANCH_NAME=${GITHUB_REF#refs/heads/}
ID="$BRANCH_NAME-$SHORT_SHA"
DISPLAY_ID="$BRANCH_NAME-$SHORT_SHA"
fi
# Set outputs
echo "filename=$ID" >> $GITHUB_OUTPUT
echo "display_name=$DISPLAY_ID" >> $GITHUB_OUTPUT

View File

@ -10,7 +10,7 @@ def extract_packages(data):
for line in lines:
# Regex to match the package format and capture features inside brackets
match = re.match(
r"\s*\*?\s+([^\[\]:]+)(?:\[(.*?)\])?:([^\[\]@]+)@([^\s]+)\s+--", line
r"\s*\*\s+([^\[\]:]+)(?:\[(.*?)\])?:([^\[\]@]+)@([^\s]+)\s+--", line
)
if match:
package_name = match.group(1)

View File

@ -1,13 +1,12 @@
---
name: 🍎 Build - MacOS Qt6
on:
push:
branches:
- master
- release-*
pull_request:
release:
types: ['published']
# push:
# branches:
# - main
# pull_request:
# release:
# types: ['published']
workflow_dispatch:
concurrency:
@ -19,9 +18,9 @@ jobs:
strategy:
matrix:
include:
- os: macos-13
triplet: x64-osx-dynamic-release
deployment-target: "10.15"
# - os: macos-13
# triplet: x64-osx
# deployment-target: "10.15"
- os: macos-14
triplet: arm64-osx-dynamic-release
deployment-target: "11.0"
@ -43,13 +42,9 @@ jobs:
id: setup-vcpkg
uses: ./.github/actions/setup-vcpkg
- name: 🎲 Get artifact ids
id: workflow-artifact-ids
uses: ./.github/actions/get-workflow-artifact-ids
- name: 🔨 Prepare build env
run: |
brew install automake bison flex gnu-sed autoconf-archive nasm libtool fdupes
brew install automake bison flex gnu-sed create-dmg autoconf-archive nasm libtool fdupes
echo $(brew --prefix bison)/bin >> $GITHUB_PATH
echo $(brew --prefix flex)/bin >> $GITHUB_PATH
echo $(brew --prefix libtool)/bin >> $GITHUB_PATH
@ -63,22 +58,7 @@ jobs:
with:
xcode-version: latest-stable
- name: 🛍️ Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
max-size: 500M
key: build-ccache-${{ matrix.triplet }}-qt6-${{ github.event.pull_request.base.ref || github.ref_name }}
save: ${{ github.event_name == 'push' }}
- name: 🛍️ Tune ccache configuration
shell: bash
run: |
# To make ccache work properly with precompiled headers
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
- name: 🌱 Install dependencies and generate project files
env:
X_VCPKG_ASSET_SOURCES: x-azurl,https://assetcache.open-vcpkg.org/assetcache,,read
run: |
echo "VCPKG_ROOT: ${VCPKG_ROOT}"
@ -87,22 +67,18 @@ jobs:
cmake -S . \
-G Ninja \
-B build \
-D QGIS_APP_NAME="QGIS-${{steps.workflow-artifact-ids.outputs.display-name}}" \
-D WITH_VCPKG=ON \
-D BUILD_WITH_QT6=ON \
-D WITH_QTWEBKIT=OFF \
-D WITH_BINDINGS=ON \
-D WITH_ORACLE=ON \
-D QGIS_MACAPP_FRAMEWORK=OFF \
-D VCPKG_TARGET_TRIPLET="${{ matrix.triplet }}" \
-D VCPKG_HOST_TRIPLET="${{ matrix.triplet }}" \
-D VCPKG_INSTALL_OPTIONS="--only-binarycaching" \
-D CMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.deployment-target }} \
-D ENABLE_UNITY_BUILDS=ON \
-D NUGET_USERNAME=${{ github.actor }} \
-D NUGET_SOURCE="https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
-D NUGET_TOKEN=${{ secrets.GITHUB_TOKEN }} || true
fdupes -q -r -1 build/vcpkg_installed/${{ matrix.triplet }}/lib | grep libQt | while read line; do master=""; for file in ${line[*]}; do if [[ "x${master}" == "x" ]]; then master=$file; else rm "${file}"; ln -s $(basename "${master}") "${file}"; fi; done; done
fdupes -r -1 build/vcpkg_installed/arm64-osx-dynamic/lib | grep libQt | while read line; do master=""; for file in ${line[*]}; do if [[ "x${master}" == "x" ]]; then master=$file; else rm "${file}"; ln -s $(basename "${master}") "${file}"; fi; done; done
cmake -D VCPKG_INSTALL_OPTIONS="" build
@ -123,100 +99,10 @@ jobs:
if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
uses: actions/upload-artifact@v4
with:
name: qgis-sdk-${{ matrix.triplet }}
name: kadas-albireo2-sdk-${{ matrix.triplet }}
path: |
sdk/vcpkg-export-*.zip
- name: 🌋 Build
run: |
# We make sure the target "all" is built before bundling
# Ideally, we would specify each target that is required to be installed, but this workaround is sufficient for now
cmake --build build
cmake --build build --target bundle
- name: Archive app
run: |
gtar -cpvzf qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}.tar.gz ./build/_CPack_Packages/Darwin/External/*/*.app
- name: 📤 Upload app
uses: actions/upload-artifact@v4
with:
name: qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}
path: |
qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}.tar.gz
schedule_download_comment:
name: Create dmg
runs-on: macos-latest
needs: build
steps:
- name: 🐣 Checkout
uses: actions/checkout@v4
- name: 🔨 Prepare build env
run: |
brew install create-dmg
- name: 🎲 Get artifact ids
id: workflow-artifact-ids
uses: ./.github/actions/get-workflow-artifact-ids
- name: 📤 Download app
uses: actions/download-artifact@v4
with:
pattern: qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-*
path: |
artifacts
- name: Create universal app
run: |
mkdir -p x64
gtar --strip-components=5 -zxf ./artifacts/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-x64-osx-dynamic-release/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-x64-osx-dynamic-release.tar.gz -C x64
mkdir -p arm64
gtar --strip-components=5 -zxf ./artifacts/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-arm64-osx-dynamic-release/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-arm64-osx-dynamic-release.tar.gz -C arm64
pip install lipomerge
lipomerge ./x64 ./arm64 universal
- name: Create dmg
run: |
QGIS_APP_NAME=QGIS-"${{steps.workflow-artifact-ids.outputs.display-name}}"
create-dmg --volname "${QGIS_APP_NAME} Installer" \
--hide-extension ${QGIS_APP_NAME}.app \
--volicon "$(pwd)/images/icons/mac/qgis.icns" \
--background "$(pwd)/platform/macos/installer_background.png" \
--window-pos 200 120 \
--window-size 512 320 \
--icon-size 100 \
--icon "${QGIS_APP_NAME}.app" 130 160 \
--app-drop-link 400 155 \
${QGIS_APP_NAME}-Installer.dmg \
universal/*/*.app
- name: 📤 Upload app
uses: actions/upload-artifact@v4
id: artifact-mac-qt6
with:
name: qgis-${{steps.workflow-artifact-ids.outputs.filename}}-dmg
path: |
*.dmg
- name: Upload release assets
uses: AButler/upload-release-assets@v3.0
if: ${{ github.event_name == 'release' }}
with:
files: '*.dmg'
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Schedule download comment
uses: ./.github/actions/post_sticky_comment
if: github.event_name == 'pull_request'
with:
marker: macos-qt6
body: |
### 🍎 MacOS Qt6 builds
Download [MacOS Qt6 builds of this PR for testing](${{ steps.artifact-mac-qt6.outputs.artifact-url }}).
_This installer is not signed, `control`+click > `open` the app to avoid the warning_
*(Built from commit ${{ github.event.pull_request.head.sha }})*
pr: ${{ github.event.number }}

View File

@ -24,10 +24,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: '3.13'
python-version: '3.10'
- name: Install requirements
run: |
wget https://www.doxygen.nl/files/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
@ -176,10 +176,10 @@ jobs:
sip_check:
runs-on: ubuntu-latest
steps:
- name: Set up Python
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.13'
python-version: '3.12'
- name: Install Requirements
run: |
python -m pip install --upgrade pip
@ -214,6 +214,6 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
python-version: '3.12'
- name: Run Check
run: python3 scripts/includemocs.py src --dry-run

140
.github/workflows/macos-build.yml vendored Normal file
View File

@ -0,0 +1,140 @@
name: 🍏 Mac OS build
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
push:
branches:
- master
- release-**
- queued_ltr_backports
paths:
pull_request:
branches:
- master
- release-**
- queued_ltr_backports
paths:
permissions:
contents: read
env:
QT_VERSION: 5.15.2
QGIS_DEPS_VERSION: 0.9
QGIS_DEPS_PATCH_VERSION: 0
CCACHE_DIR: /Users/runner/work/ccache
BUILD_DIR: /Users/runner/work/QGIS/build-QGIS
# apparently we cannot cache /opt directory as it fails to restore
# so we copy the deps in the home directory
DEPS_CACHE_DIR: /Users/runner/work/deps-cache
jobs:
mac_os_build:
if: github.repository == 'qgis/QGIS'
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- name: Restore build cache
uses: actions/cache/restore@v4
with:
path: ${{ env.CCACHE_DIR }}
key: build-ccache-mac-${{ github.event.pull_request.base.ref || github.ref_name }}
restore-keys: |
build-ccache-mac-master
- name: Cache Qt
id: cache-qt
uses: actions/cache@v4
with:
path: ${{ env.DEPS_CACHE_DIR }}/Qt/${{ env.QT_VERSION }}
key: mac-qt-${{ env.QT_VERSION }}
- name: Restore Qt
if: steps.cache-qt.outputs.cache-hit == 'true'
run: |
sudo mkdir -p /opt
sudo mkdir -p /opt/Qt
sudo cp -r ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} /opt/Qt/${QT_VERSION}
- name: Download Qt
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
wget https://qgis.org/downloads/macos/deps/qt-${QT_VERSION}.tar.gz
mkdir -p ${DEPS_CACHE_DIR}
mkdir -p ${DEPS_CACHE_DIR}/Qt
# QGIS-deps caching
- name: Cache qgis-deps
id: cache-deps
uses: actions/cache@v4
with:
path: ${{ env.DEPS_CACHE_DIR }}/QGIS/qgis-deps-${{ env.QGIS_DEPS_VERSION }}.${{ env.QGIS_DEPS_PATCH_VERSION }}
key: mac-qgis-deps-${{ env.QGIS_DEPS_VERSION }}.${{ env.QGIS_DEPS_PATCH_VERSION }}
- name: Restore qgis-deps
if: steps.cache-deps.outputs.cache-hit == 'true'
run: |
sudo mkdir -p /opt
sudo mkdir -p /opt/QGIS
sudo cp -r ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION} /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}
- name: Download qgis-deps
if: steps.cache-deps.outputs.cache-hit != 'true'
run: |
wget https://qgis.org/downloads/macos/deps/qgis-deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION}.tar.gz
mkdir -p ${DEPS_CACHE_DIR}
mkdir -p ${DEPS_CACHE_DIR}/QGIS
- name: Install Qt and deps
env:
QT_ALREADY_CACHED: ${{ steps.cache-qt.outputs.cache-hit }}
QGIS_DEPS_ALREADY_CACHED: ${{ steps.cache-deps.outputs.cache-hit }}
run: |
wget https://qgis.org/downloads/macos/deps/install_qgis_deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION}.bash
chmod +x ./install_qgis_deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION}.bash
echo ::group::Install deps
sudo ./install_qgis_deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION}.bash
echo ::endgroup::
[[ ${QT_ALREADY_CACHED} != "true" ]] && cp -r /opt/Qt/${QT_VERSION} ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} || true
[[ ${QGIS_DEPS_ALREADY_CACHED} != "true" ]] && cp -r /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION} ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION}.${QGIS_DEPS_PATCH_VERSION} || true
- name: Install ccache
run: |
mkdir -p ${CCACHE_DIR}
brew install ccache
ccache --set-config=max_size=2.0G
# To make ccache work properly with precompiled headers
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
ccache -s
- name: Run cmake
run: |
mkdir -p ${BUILD_DIR}
cd ${BUILD_DIR}
PATH=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage/bin:$PATH \
cmake -DQGIS_MAC_DEPS_DIR=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage \
-DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/clang_64 \
-DWITH_BINDINGS=TRUE \
-DWITH_3D=TRUE \
-DWITH_DRACO=FALSE \
-DWITH_PDAL=TRUE \
-DWITH_EPT=TRUE \
../QGIS
- name: Build QGIS
run: |
cd ${BUILD_DIR}
make -j $(sysctl -n hw.ncpu)
- name: Save build cache for push only
uses: actions/cache/save@v4
if: ${{ github.event_name == 'push' }}
with:
path: ${{ env.CCACHE_DIR }}
key: build-ccache-mac-${{ github.ref_name }}-${{ github.run_id }}

View File

@ -14,7 +14,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.13'
python-version: '3.12'
- name: Install Requirements
run: pip install nose2 mock termcolor pyyaml

View File

@ -24,7 +24,6 @@ set (WITH_3D TRUE CACHE BOOL "Determines whether QGIS 3D library should be built
set (WITH_QGIS_PROCESS TRUE CACHE BOOL "Determines whether the standalone \"qgis_process\" tool should be built")
set (WITH_DESKTOP TRUE CACHE BOOL "Determines whether QGIS desktop should be built")
set (WITH_GUI TRUE CACHE BOOL "Determines whether QGIS GUI library should be built")
set (WITH_ORACLE FALSE CACHE BOOL "Determines whether Oracle support should be built")
set(WITH_VCPKG FALSE CACHE BOOL "Use the vcpkg submodule for dependency management.")
set(SDK_PATH "" CACHE STRING "Build with VCPKG SDK")
@ -47,11 +46,10 @@ endif()
if(WITH_VCPKG)
set(TARGET_SYSROOT "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}")
if(WIN32)
list(APPEND CMAKE_PROGRAM_PATH "${TARGET_SYSROOT}/tools/python3/Scripts/")
list(APPEND CMAKE_PROGRAM_PATH "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}/tools/python3/Scripts/")
else()
list(APPEND CMAKE_PROGRAM_PATH "${TARGET_SYSROOT}/bin")
list(APPEND CMAKE_PROGRAM_PATH "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}/bin")
endif()
set(PREFER_INTERNAL_LIBS FALSE)
else()
@ -67,7 +65,11 @@ set(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINO
set(RELEASE_NAME "Master")
project(qgis VERSION ${COMPLETE_VERSION})
set(QGIS_APP_NAME "qgis" CACHE STRING "The main app name and bundle name")
if (APPLE)
set(QGIS_APP_NAME "QGIS")
else()
set(QGIS_APP_NAME "qgis")
endif()
# Note the version no is Mmmpp for Major/minor/patch, 0-padded, thus '10100' for 1.1.0
math(EXPR QGIS_VERSION_INT "${CPACK_PACKAGE_VERSION_MAJOR}*10000+${CPACK_PACKAGE_VERSION_MINOR}*100+${CPACK_PACKAGE_VERSION_PATCH}")
@ -75,6 +77,21 @@ message(STATUS "QGIS version: ${COMPLETE_VERSION} ${RELEASE_NAME} (${QGIS_VERSIO
set (ENABLE_LOCAL_BUILD_SHORTCUTS FALSE CACHE BOOL "Disables some build steps which are only relevant for releases to speed up compilation time for development")
#############################################################
if (APPLE)
# QGIS custom dependencies package from qgis/QGIS-Mac-Packager
# they can be downloaded from https://download.qgis.org/downloads/macos/deps/
# and extracted to /opt/QGIS/qgis-deps-<deps-version>/stage
set (QGIS_MAC_DEPS_DIR "" CACHE PATH "Path to QGIS Mac custom dependencies directory")
# Setup LIB_DIR and CMAKE_PREFIX_PATH to help CMake's
# find_packages to look for these libraries instead of system libraries
if ( QGIS_MAC_DEPS_DIR )
set(ENV{LIB_DIR} ${QGIS_MAC_DEPS_DIR})
list(APPEND CMAKE_PREFIX_PATH ${QGIS_MAC_DEPS_DIR})
endif()
endif()
#############################################################
# Configure OpenCL if available
set(HAVE_OPENCL FALSE)
@ -332,6 +349,7 @@ if(WITH_CORE)
set (WITH_QSPATIALITE FALSE CACHE BOOL "Determines whether QSPATIALITE sql driver should be built")
endif()
set (WITH_ORACLE FALSE CACHE BOOL "Determines whether Oracle support should be built")
if(WITH_ORACLE)
set(HAVE_ORACLE TRUE)
set(ORACLE_INCLUDEDIR "" CACHE STRING "Path to OCI headers")
@ -895,27 +913,6 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" ST
include("cmake/modules/linker.cmake")
endif()
set(MIN_PYTHON_VERSION "3.11")
set(Python_FIND_FRAMEWORK "LAST")
if (WITH_BINDINGS)
find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter Development)
else()
find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter)
endif()
# Fix python site-packages for Fedora
# See https://github.com/qgis/QGIS/issues/54348#issuecomment-1694216152
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if(EXISTS "/etc/fedora-release")
EXECUTE_PROCESS(COMMAND ${Python_EXECUTABLE} -c "import sysconfig;print(sysconfig.get_path(\"platlib\", \"rpm_prefix\"), end=\"\")" OUTPUT_VARIABLE Python_SITEARCH)
endif()
endif()
message("-- Found Python executable: ${Python_EXECUTABLE} (version ${Python_VERSION})")
message("-- Python library: ${Python_LIBRARIES}")
message("-- Python site-packages: ${Python_SITEARCH}")
#############################################################
# platform specific stuff
if (WITH_CORE)
@ -953,57 +950,68 @@ if (WITH_CORE)
else()
if(APPLE)
set(QGIS_MAC_BUNDLE TRUE CACHE BOOL "Install into a mac bundle")
set(QGIS_MACAPP_FRAMEWORK TRUE CACHE BOOL "Build as a framework on OSX")
endif()
if (APPLE AND QGIS_MAC_BUNDLE)
set(CMAKE_MACOSX_RPATH ON) # If this is off, the path will be stripped (completely) at install time, we want to preserve the `@rpath` prefix
set(CMAKE_SKIP_INSTALL_RPATH TRUE)
if (APPLE AND QGIS_MACAPP_FRAMEWORK)
if (POLICY CMP0042) # in CMake 3.0.0+
set (CMAKE_MACOSX_RPATH OFF) # otherwise ON by default
endif()
if (POLICY CMP0068) # in CMake 3.9.0+
cmake_policy(SET CMP0068 NEW)
endif()
# for Mac OS X, everything is put inside an application bundle
# save the root install prefix for the app later
set (QGIS_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set (QGIS_MACAPP_PREFIX ${CMAKE_INSTALL_PREFIX}/${QGIS_APP_NAME}.app/Contents)
# common prefix for components, let cmake handle it
set (CMAKE_INSTALL_PREFIX ${QGIS_MACAPP_PREFIX}/MacOS)
# 5 bundling levels, each includes previous
# -1 nothing
# 0 fixup the library paths for all QGIS libraries with @loader_path
# 1 Qt frameworks
# 2 non-system libraries, "standard"
# 3 non-system frameworks, "standalone"
set (QGIS_MACAPP_BUNDLE 1 CACHE STRING "What to bundle into app package")
set (QGIS_MACAPP_BUNDLE_USER "" CACHE STRING "Path to user bundling script")
set (QGIS_MACAPP_INSTALL_DEV FALSE CACHE BOOL "Install developer frameworks")
set (QGIS_MACAPP_DEV_PREFIX "/Library/Frameworks" CACHE STRING "Path to install developer frameworks")
set(APP_CONTENTS_DIR "Contents")
set(APP_MACOS_DIR "${APP_CONTENTS_DIR}/MacOS")
set(APP_FRAMEWORKS_DIR "${APP_CONTENTS_DIR}/Frameworks")
set(APP_RESOURCES_DIR "${APP_CONTENTS_DIR}/Resources")
set(APP_PLUGINS_DIR "${APP_CONTENTS_DIR}/PlugIns")
set (DEFAULT_BIN_SUBDIR bin)
set (QGIS_BIN_SUBDIR_REV ..)
set (DEFAULT_CGIBIN_SUBDIR fcgi-bin)
set (QGIS_CGIBIN_SUBDIR_REV ..)
set (DEFAULT_LIB_SUBDIR lib)
set (QGIS_LIB_SUBDIR_REV ..)
set (QGIS_FW_SUBDIR ../Frameworks)
set (QGIS_FW_SUBDIR_REV ../MacOS)
set (DEFAULT_DATA_SUBDIR ../Resources)
set (QGIS_DATA_SUBDIR_REV ../MacOS)
set (DEFAULT_LIBEXEC_SUBDIR lib/qgis)
set (QGIS_LIBEXEC_SUBDIR_REV ../..)
set (DEFAULT_PLUGIN_SUBDIR ../PlugIns/qgis)
set (QGIS_PLUGIN_SUBDIR_REV ../../MacOS)
set (DEFAULT_INCLUDE_SUBDIR include/qgis)
set (DEFAULT_QML_SUBDIR qml)
cmake_path(RELATIVE_PATH Python_SITEARCH BASE_DIRECTORY "${TARGET_SYSROOT}" OUTPUT_VARIABLE _RELATIVE_SITEARCH)
# Set server moodules path to DEFAULT_LIBEXEC_SUBDIR+'/server'
set (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
# path for framework references when running from build directory
# changed later to reference in-app resources upon install
set (CMAKE_INSTALL_NAME_DIR ${CMAKE_BINARY_DIR}/output/lib)
# recent cmakes force SDKs, recent SDKs don't have user symlinks
# need to find non-system frameworks
# cmake bug #0007250 - CMAKE_SHARED_LINKER_FLAGS ignored when creating
# a framework, so these need to be manually handled with LINK_FLAGS options
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -F/Library/Frameworks")
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -F/Library/Frameworks")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -F/Library/Frameworks")
set(DEFAULT_BIN_SUBDIR ${APP_MACOS_DIR})
set(DEFAULT_LIB_SUBDIR ${APP_FRAMEWORKS_DIR})
set(DEFAULT_DATA_SUBDIR ${APP_RESOURCES_DIR}/qgis)
set(DEFAULT_LIBEXEC_SUBDIR ${APP_MACOS_DIR})
set(DEFAULT_PLUGIN_SUBDIR ${APP_PLUGINS_DIR}/qgis)
set(DEFAULT_INCLUDE_SUBDIR include/qgis)
set(DEFAULT_QML_SUBDIR ${APP_RESOURCES_DIR}/qgis/qml)
set(DEFAULT_PYTHON_SUBDIR ${APP_FRAMEWORKS_DIR}/${_RELATIVE_SITEARCH})
else()
# UNIX
set (DEFAULT_BIN_SUBDIR bin)
# From https://www.cyberciti.biz/faq/how-do-i-find-the-url-for-my-cgi-bin/
execute_process(COMMAND lsb_release -a OUTPUT_VARIABLE LSB_RELEASE_A)
if(EXISTS "/etc/fedora-release")
# in /var/www/cgi-bin
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "FreeBSD")
# in /usr/local/www/cgi-bin/
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "BSD")
# in /usr/local/libexec/cgi-bin/
set (DEFAULT_CGIBIN_SUBDIR libexec/cgi-bin)
elseif ("${LSB_RELEASE_A}" MATCHES "Ubuntu" OR "${LSB_RELEASE_A}" MATCHES "Debian" OR "${LSB_RELEASE_A}" MATCHES "Mint")
# in /usr/lib/cgi-bin/
set (DEFAULT_CGIBIN_SUBDIR lib/cgi-bin)
else()
# others: Red Hat/CentOS/Rocky/Alma Linux
# in /var/www/cgi-bin/
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
endif()
set (DEFAULT_CGIBIN_SUBDIR bin)
set (DEFAULT_LIB_SUBDIR lib${LIB_SUFFIX})
set (DEFAULT_DATA_SUBDIR share/qgis)
set (DEFAULT_LIBEXEC_SUBDIR lib${LIB_SUFFIX}/qgis)
@ -1012,6 +1020,13 @@ if (WITH_CORE)
set (DEFAULT_QML_SUBDIR qml)
set (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
# QGIS_MACAPP_FRAMEWORK=FALSE
if(APPLE)
set (QGIS_MACAPP_BUNDLE -1)
set (CMAKE_FRAMEWORK FALSE)
set (QGIS_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
endif()
endif()
endif()
@ -1119,6 +1134,28 @@ option(ENABLE_UNITY_BUILDS "Enable Unity builds, that is compiling several .cpp
#############################################################
# Python
set(MIN_PYTHON_VERSION "3.9")
set(Python_FIND_FRAMEWORK "LAST")
if (WITH_BINDINGS)
find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter Development)
else()
find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter)
endif()
# Fix python site-packages for Fedora
# See https://github.com/qgis/QGIS/issues/54348#issuecomment-1694216152
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if(EXISTS "/etc/fedora-release")
EXECUTE_PROCESS(COMMAND ${Python_EXECUTABLE} -c "import sysconfig;print(sysconfig.get_path(\"platlib\", \"rpm_prefix\"), end=\"\")" OUTPUT_VARIABLE Python_SITEARCH)
endif()
endif()
message("-- Found Python executable: ${Python_EXECUTABLE} (version ${Python_VERSION})")
message("-- Python library: ${Python_LIBRARIES}")
message("-- Python site-packages: ${Python_SITEARCH}")
if (WITH_CORE AND WITH_BINDINGS)
set(PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python)
set (QGIS_PYTHON_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/qgis)
@ -1151,12 +1188,8 @@ if (WITH_CORE AND WITH_BINDINGS)
set(SIP_INCLUDES ${PYQT_SIP_DIR} ${CMAKE_SOURCE_DIR}/python)
set(SIP_CONCAT_PARTS 25)
if(BINDINGS_GLOBAL_INSTALL)
set(QGIS_PYTHON_INSTALL_DIR ${Python_SITEARCH})
elseif(DEFINED DEFAULT_PYTHON_SUBDIR)
set(QGIS_PYTHON_INSTALL_DIR ${DEFAULT_PYTHON_SUBDIR})
else()
set(QGIS_PYTHON_INSTALL_DIR ${QGIS_DATA_DIR}/python)
if (NOT BINDINGS_GLOBAL_INSTALL)
set(Python_SITEARCH ${QGIS_DATA_DIR}/python)
endif()
if (WITH_CUSTOM_WIDGETS)
@ -1213,6 +1246,22 @@ if (WITH_CORE)
add_subdirectory(python)
endif()
if (APPLE)
# must be last for install, so install_name_tool can do its work
add_subdirectory(mac)
# allow QGIS to be run directly from build directory and to run unit tests
execute_process(COMMAND /bin/mkdir -p "${QGIS_OUTPUT_DIRECTORY}/lib")
execute_process(
COMMAND /bin/ln -fs ../../Plugins/qgis/qgisgrass6.framework lib/
WORKING_DIRECTORY "${QGIS_OUTPUT_DIRECTORY}"
)
execute_process(
COMMAND /bin/ln -fs ../../Plugins/qgis/qgisgrass7.framework lib/
WORKING_DIRECTORY "${QGIS_OUTPUT_DIRECTORY}"
)
endif()
# manual page - makes sense only on unix systems
if (UNIX AND NOT APPLE)
install (FILES qgis.1 DESTINATION ${QGIS_MANUAL_DIR}/man1)
@ -1252,8 +1301,8 @@ endif()
#############################################################
# Enable packaging
if (WITH_CORE)
include(VcpkgInstallDeps)
include(Bundle)
include(VcpkgInstallDeps)
endif()
if (UNIX AND NOT APPLE)

View File

@ -102,7 +102,7 @@ Required build tools:
* CMake >= 3.12.0
* Flex >= 2.5.6
* Bison >= 2.4
* Python >= 3.11
* Python >= 3.7
Required build dependencies:
@ -1052,7 +1052,7 @@ Install and initialize vcpkg
Install build tools using [homebrew](https://brew.sh/)
```sh
brew install git cmake flex bison automake autoconf autoconf-archive libtool nasm ninja
brew install git cmake flex bison automake autoconf libtool nasm ninja
```
Get the QGIS source code
@ -1087,8 +1087,10 @@ cmake -S . \
-D BUILD_WITH_QT6=ON \
-D WITH_QTWEBKIT=OFF \
-D WITH_BINDINGS=ON \
-D QGIS_MACAPP_FRAMEWORK=OFF \
-D VCPKG_TARGET_TRIPLET="$TRIPLET" \
-D VCPKG_HOST_TRIPLET="$TRIPLET"
-D VCPKG_HOST_TRIPLET="$TRIPLET" \
-D CREATE_MACOSX_BUNDLE=OFF
```
Build (switch the target to `Release` if you do not want to debug)

View File

@ -2,7 +2,7 @@ set(CPACK_GENERATOR)
set(CPACK_OUTPUT_CONFIG_FILE "${CMAKE_BINARY_DIR}/BundleConfig.cmake")
add_custom_target(bundle
COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake" "--verbose"
COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake"
COMMENT "Running CPACK. Please wait..."
DEPENDS qgis)
@ -22,6 +22,7 @@ endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "QGIS")
set(CPACK_PACKAGE_VENDOR "Open Source Geospatial Foundation")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "QGIS ${COMPLETE_VERSION}")
set(CPACK_PACKAGE_EXECUTABLES "qgis" "QGIS")
@ -43,22 +44,4 @@ if(CREATE_ZIP)
list(APPEND CPACK_GENERATOR "ZIP")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND QGIS_MAC_BUNDLE)
set(CREATE_DMG FALSE CACHE BOOL "Create a dmg bundle")
set(PYMACDEPLOYQT_EXECUTABLE "${CMAKE_SOURCE_DIR}/platform/macos/pymacdeployqt.py")
configure_file("${CMAKE_SOURCE_DIR}/platform/macos/Info.plist.in" "${CMAKE_BINARY_DIR}/platform//macos/Info.plist" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/platform/macos/Info.plist" DESTINATION "${APP_CONTENTS_DIR}")
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
set(CPACK_DMG_FORMAT "UDBZ")
list(APPEND CPACK_GENERATOR "External")
message(STATUS " + macdeployqt/DMG YES ")
configure_file(${CMAKE_SOURCE_DIR}/platform/macos/CPackMacDeployQt.cmake.in "${CMAKE_BINARY_DIR}/CPackExternal.cmake" @ONLY)
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake")
set(CPACK_EXTERNAL_ENABLE_STAGING ON)
set(CPACK_PACKAGING_INSTALL_PREFIX "/${QGIS_APP_NAME}.app")
endif()
include(CPack)

222
cmake/MacBundleMacros.cmake Normal file
View File

@ -0,0 +1,222 @@
# QGIS Mac Bundle Macros
# BundleUtilities has functions to bundle and fixup libraries into an
# application package, but it's all-or-nothing and is missing some features:
#
# - @loader_path
# - helper functions can't get install_name, just dependencies
# the following cmakecache vars must be set, redefine them
# with config-file substitutions in install-run scripts:
#
# CPACK_PACKAGE_VERSION_MAJOR, CPACK_PACKAGE_VERSION_MINOR
# CMAKE_INSTALL_PREFIX, CMAKE_VERBOSE_MAKEFILE, CMAKE_BUILD_TYPE
# CMAKE_OSX_ARCHITECTURES
# QGIS_APP_NAME
# QGIS_MACAPP_PREFIX
# QGIS_*_SUBDIR, QGIS_*_SUBDIR_REV
# WITH_*
# this file must only be included after target installation is complete
# message only if verbose makefiles
FUNCTION (MYMESSAGE MSG)
IF (${CMAKE_VERBOSE_MAKEFILE})
MESSAGE (STATUS "${MSG}")
ENDIF (${CMAKE_VERBOSE_MAKEFILE})
ENDFUNCTION (MYMESSAGE)
# get the install_name of a library or framework
# regex stuff taken from GetPrerequisites
FUNCTION (GET_INSTALL_NAME LIBFILE LIBNAME OUTVAR)
IF (EXISTS "${LIBFILE}")
EXECUTE_PROCESS (COMMAND otool -L "${LIBFILE}" OUTPUT_VARIABLE iname_out)
# remove 1st line, it's just path to lib file
STRING (REGEX REPLACE ".*:\n" "" iname "${iname_out}")
IF (iname)
# find libname
STRING (REGEX MATCH "[^\n\t ]*${LIBNAME}[^\n]*" iname "${iname}")
STRING (REGEX REPLACE " \\(compatibility version .*, current version .*\\)" "" iname "${iname}")
ENDIF (iname)
SET (${OUTVAR} ${iname} PARENT_SCOPE)
ELSE ()
SET (${OUTVAR} "" PARENT_SCOPE)
ENDIF ()
ENDFUNCTION (GET_INSTALL_NAME)
# install_name_tool -change CHANGE CHANGETO CHANGEBIN
FUNCTION (INSTALLNAMETOOL_CHANGE CHANGE CHANGETO CHANGEBIN)
IF (EXISTS "${CHANGEBIN}" AND CHANGE AND CHANGETO)
# ensure CHANGEBIN is writable by user, e.g. Homebrew binaries are installed non-writable
EXECUTE_PROCESS (COMMAND chmod u+w "${CHANGEBIN}")
EXECUTE_PROCESS (COMMAND install_name_tool -change ${CHANGE} ${CHANGETO} "${CHANGEBIN}")
# if that didn't work, try a symlink-resolved id
# (some package systems, like Homebrew, heavily use symlinks; and, inter-package builds, like plugins,
# may point to the resolved location instead of the 'public' symlink installed to prefixes like /usr/local)
get_filename_component(_chgreal ${CHANGE} REALPATH)
EXECUTE_PROCESS (COMMAND install_name_tool -change ${_chgreal} ${CHANGETO} "${CHANGEBIN}")
ENDIF ()
ENDFUNCTION (INSTALLNAMETOOL_CHANGE)
# copy a framework, only specified archs, current version, debug dep on CMAKE_BUILD_TYPE
FUNCTION (COPY_FRAMEWORK FWPREFIX FWNAME FWDEST)
# reconstruct framework to avoid excessive copying, then deleting
# especially when debug variants are present
# find current version
# use python because pwd not working with WORKING_DIRECTORY param
EXECUTE_PROCESS (
COMMAND python -c "import os.path\nprint(os.path.realpath(\"${FWPREFIX}/${FWNAME}.framework/Versions/Current\"))"
OUTPUT_VARIABLE FWDIRPHYS
)
STRING (STRIP "${FWDIRPHYS}" FWDIRPHYS)
IF (IS_DIRECTORY "${FWDIRPHYS}")
STRING (REGEX MATCH "[^/\n]+$" FWVER "${FWDIRPHYS}")
EXECUTE_PROCESS (COMMAND mkdir -p "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}")
EXECUTE_PROCESS (COMMAND ln -sfn ${FWVER} "${FWDEST}/${FWNAME}.framework/Versions/Current")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWNAME}" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}/${FWNAME}")
EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${FWNAME} "${FWDEST}/${FWNAME}.framework/${FWNAME}")
IF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources")
EXECUTE_PROCESS (COMMAND cp -Rfp "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}")
EXECUTE_PROCESS (COMMAND ln -sfn Versions/Current/Resources "${FWDEST}/${FWNAME}.framework/Resources")
ENDIF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources")
# ensure writable by user, e.g. Homebrew frameworks are installed non-writable
EXECUTE_PROCESS (COMMAND chmod -R u+w "${FWDEST}/${FWNAME}.framework")
EXECUTE_PROCESS (COMMAND install_name_tool -id "${ATEXECUTABLE}/${QGIS_FW_SUBDIR}/${FWNAME}" "${FWDEST}/${FWNAME}.framework/${FWNAME}")
# debug variants
SET (FWD "${FWNAME}_debug")
IF ("${FWDEBUG}" STREQUAL "Debug" AND EXISTS "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWD}")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWD}" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}/${FWD}")
EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${FWD} "${FWDEST}/${FWNAME}.framework/${FWD}")
IF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/${FWD}.dSYM")
EXECUTE_PROCESS (COMMAND ditto -X ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/${FWD}.dSYM" "${FWDEST}/${FWNAME}.framework")
ENDIF ()
ENDIF ()
ENDIF ()
ENDFUNCTION (COPY_FRAMEWORK)
# update a library path in all QGIS binary files
# if dylib, change LIBFROM to LIBTO as is
# else assumes it's a framework, change LIBFROM to LIBTO.framework/LIBTO
FUNCTION (UPDATEQGISPATHS LIBFROM LIBTO)
IF (LIBFROM)
STRING (REGEX MATCH "\\.(dylib|so)$" ISLIB "${LIBTO}")
IF (ISLIB)
SET (LIBPOST "${LIBTO}")
SET (LIBMID "${QGIS_LIB_SUBDIR}")
ElSE ()
SET (LIBPOST "${LIBTO}.framework/${LIBTO}")
SET (LIBMID "${QGIS_FW_SUBDIR}")
ENDIF ()
SET (LIB_CHG_TO "${ATEXECUTABLE}/${LIBMID}/${LIBPOST}")
# app - always @executable_path
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QAPPDIR}/${QGIS_APP_NAME}")
# qgis helper apps - don't link anything else than Qt/Qgis
FOREACH (QA ${QGAPPLIST})
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QBINDIR}/${QA}.app/Contents/MacOS/${QA}")
ENDFOREACH (QA)
# qgis-mapserver
IF (${WITH_SERVER})
SET (LIB_CHG_TO "${ATEXECUTABLE}/${QGIS_CGIBIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QCGIDIR}/qgis_mapserv.fcgi")
ENDIF ()
# libs
# bundled frameworks can use short relative path
IF (ISLIB)
SET (LIB_CHG_TO "${ATLOADER}/../../../${QGIS_FW_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
ElSE ()
SET (LIB_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
ENDIF ()
FOREACH (QL ${QGFWLIST})
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QFWDIR}/${QL}.framework/${QL}")
ENDFOREACH (QL)
# non-framework qgis libs
SET (LIB_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
FOREACH (QL ${QGLIBLIST})
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBDIR}/${QL}")
ENDFOREACH (QL)
# crssync
SET (LIB_CHG_TO "${ATEXECUTABLE}/${QGIS_LIBEXEC_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBXDIR}/crssync")
# GRASS libexec stuff
FOREACH (QG ${QGRASSEXECLIST})
IF (EXISTS "${QLIBXDIR}/grass/${QG}")
SET (LIB_CHG_TO "${ATLOADER}/../../${QGIS_LIBEXEC_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBXDIR}/grass/${QG}")
ENDIF ()
ENDFOREACH (QG)
# plugins
SET (LIB_CHG_TO "${ATLOADER}/${QGIS_PLUGIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
FOREACH (QP ${QGPLUGLIST})
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QP}")
ENDFOREACH (QP)
# quick plugin
SET (LIB_CHG_TO "${ATLOADER}/../../${LIBMID}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QAPPDIR}/qml/QgsQuick/libqgis_quick_plugin.dylib")
# qgis python
SET (LIB_CHG_TO "${ATLOADER}/../../${QGIS_DATA_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
FOREACH (PG ${QGPYLIST})
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${PG}")
ENDFOREACH (PG)
# bin - nothing yet
# SET (LIB_CHG_TO "${ATLOADER}/${QGIS_BIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
#FOREACH (PB ...)
# INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QBINDIR}/${PB}")
#ENDFOREACH (PB)
ENDIF (LIBFROM)
ENDFUNCTION (UPDATEQGISPATHS)
# Find directory path for a known Python module (or package) directory or file name
# see: PYTHON_MODULE_PATHS in 0vars.cmake.in
FUNCTION (PYTHONMODULEDIR MOD_NAME OUTVAR)
FOREACH (MOD_PATH ${PYTHON_MODULE_PATHS})
IF (EXISTS "${MOD_PATH}/${MOD_NAME}")
SET (${OUTVAR} "${MOD_PATH}" PARENT_SCOPE)
RETURN()
ENDIF()
ENDFOREACH (MOD_PATH)
SET (${OUTVAR} "" PARENT_SCOPE)
ENDFUNCTION (PYTHONMODULEDIR)
SET (ATEXECUTABLE "@executable_path")
SET (ATLOADER "@loader_path")
SET (Q_FWVER ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR})
# install destinations
SET (QAPPDIRC "$ENV{DESTDIR}${QGIS_MACAPP_PREFIX}")
SET (QAPPDIR "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}")
SET (QFWDIR "${QAPPDIR}/${QGIS_FW_SUBDIR}")
SET (QBINDIR "${QAPPDIR}/${QGIS_BIN_SUBDIR}")
SET (QCGIDIR "${QAPPDIR}/${QGIS_CGIBIN_SUBDIR}")
SET (QLIBDIR "${QAPPDIR}/${QGIS_LIB_SUBDIR}")
SET (QLIBXDIR "${QAPPDIR}/${QGIS_LIBEXEC_SUBDIR}")
SET (QDATADIR "${QAPPDIR}/${QGIS_DATA_SUBDIR}")
SET (QPLUGDIR "${QAPPDIR}/${QGIS_PLUGIN_SUBDIR}")
SET (QGISPYDIR "${QAPPDIR}/${QGIS_DATA_SUBDIR}/python")
# build arches
SET (QARCHS "")
FOREACH (QARCH ${CMAKE_OSX_ARCHITECTURES})
SET (QARCHS ${QARCHS} "--arch" "${QARCH}")
ENDFOREACH (QARCH)
# common file lists
FILE (GLOB QGFWLIST RELATIVE "${QFWDIR}" "${QFWDIR}/qgis*.framework")
# for some reason, REPLACE is stripping list seps
STRING(REPLACE ".framework" ";" QGFWLIST ${QGFWLIST})
# don't collect any library symlinks, limit to versioned libs
SET (Q_LIBVER ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR})
FILE (GLOB QGLIBLIST RELATIVE "${QLIBDIR}" "${QLIBDIR}/libqgis*.dylib" "${QLIBDIR}/qgis/server/lib*.so")
FILE (GLOB QGPLUGLIST "${QPLUGDIR}/*.so")
FILE (GLOB QGPYLIST "${QGISPYDIR}/qgis/*.so")
FILE (GLOB QGAPPLIST RELATIVE "${QBINDIR}" "${QBINDIR}/q*.app")
FILE (GLOB QGRASSEXECLIST RELATIVE "${QLIBXDIR}/grass" "${QLIBXDIR}/grass/*/*")
IF (QGAPPLIST)
STRING(REPLACE ".app" ";" QGAPPLIST ${QGAPPLIST})
ENDIF (QGAPPLIST)

View File

@ -207,5 +207,5 @@ MACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS)
)
ENDIF(WIN32)
INSTALL(TARGETS ${_logical_name} DESTINATION "${QGIS_PYTHON_INSTALL_DIR}/${_parent_module_path}")
INSTALL(TARGETS ${_logical_name} DESTINATION "${Python_SITEARCH}/${_parent_module_path}")
ENDMACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS)

View File

@ -5,15 +5,12 @@ endif()
set(VCPKG_BASE_DIR "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}")
if(MSVC)
# At least python3.dll, qgis_analysis.dll and gsl.dll are missing
# Copy everything
file(GLOB ALL_LIBS
"${VCPKG_BASE_DIR}/bin/*.dll"
)
install(FILES ${ALL_LIBS} DESTINATION "bin")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
file(GLOB ALL_LIBS
"${VCPKG_BASE_DIR}/lib/*.dylib"
)
install(FILES ${ALL_LIBS} DESTINATION "${QGIS_LIB_SUBDIR}")
endif()
set(PROJ_DATA_PATH "${VCPKG_BASE_DIR}/share/proj")
@ -22,134 +19,12 @@ if(NOT EXISTS "${PROJ_DATA_PATH}/proj.db")
message(FATAL_ERROR "proj.db not found at ${PROJ_DATA_PATH}/proj.db")
endif()
install(DIRECTORY "${PROJ_DATA_PATH}/" DESTINATION "${QGIS_DATA_SUBDIR}/proj")
install(DIRECTORY "${VCPKG_BASE_DIR}/share/gdal/" DESTINATION "${QGIS_DATA_SUBDIR}/gdal")
if(MSVC)
install(DIRECTORY "${VCPKG_BASE_DIR}/bin/Qca/crypto/" DESTINATION "${QGIS_LIB_SUBDIR}/Qt6/plugins/crypto") # QCA plugins
else()
install(DIRECTORY "${VCPKG_BASE_DIR}/bin/Qca/crypto/" DESTINATION "${APP_PLUGINS_DIR}/crypto") # QCA plugins
endif()
if(MSVC)
install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/" DESTINATION "${QGIS_LIB_SUBDIR}/Qt6") # qt plugins (qml and others)
else()
install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/plugins/" DESTINATION "${APP_PLUGINS_DIR}/") # qt plugins (qml and others)
endif()
install(DIRECTORY "${PROJ_DATA_PATH}/" DESTINATION "${CMAKE_INSTALL_DATADIR}/proj")
install(DIRECTORY "${VCPKG_BASE_DIR}/share/gdal/" DESTINATION "${CMAKE_INSTALL_DATADIR}/gdal")
install(DIRECTORY "${VCPKG_BASE_DIR}/bin/Qca/" DESTINATION "bin/Qca") # QCA plugins
install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/" DESTINATION "bin/Qt6") # qt plugins (qml and others)
if(WITH_BINDINGS)
if(MSVC)
set(_SOURCE_PYTHON_DIR "${VCPKG_BASE_DIR}/tools/python3/")
set(_TARGET_PYTHON_DIR "bin")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
cmake_path(GET Python_SITEARCH PARENT_PATH _SOURCE_PYTHON_DIR)
set(_TARGET_PYTHON_DIR "${APP_FRAMEWORKS_DIR}/lib")
get_filename_component(PYTHON_EXECUTABLE "${Python_EXECUTABLE}" NAME)
install(PROGRAMS ${Python_EXECUTABLE}
DESTINATION "${QGIS_BIN_SUBDIR}")
configure_file("${CMAKE_SOURCE_DIR}/platform/macos/python.in" "${CMAKE_BINARY_DIR}/platform/macos/python" @ONLY)
install(PROGRAMS "${CMAKE_BINARY_DIR}/platform/macos/python"
DESTINATION "${QGIS_BIN_SUBDIR}")
endif()
install(DIRECTORY "${_SOURCE_PYTHON_DIR}"
DESTINATION "${_TARGET_PYTHON_DIR}"
install(DIRECTORY "${VCPKG_BASE_DIR}/tools/python3/"
DESTINATION "bin"
PATTERN "*.sip" EXCLUDE)
endif()
function(fixup_shebang INPUT_FILE OUTPUT_VARIABLE)
get_filename_component(_FILE ${INPUT_FILE} NAME)
file(READ ${INPUT_FILE} CONTENTS)
string(REGEX MATCH "^#!" SHEBANG_PRESENT "${CONTENTS}")
if (NOT SHEBANG_PRESENT)
message(FATAL_ERROR "File ${INPUT_FILE} does not start with a shebang (#!).")
endif()
# Replace the first line
string(REGEX REPLACE "^#![^\n]*" "#!/bin/sh\n\"exec\" \"\`dirname \$0\`/python\" \"\$0\" \"\$@\"" TRANSFORMED_CONTENTS "${CONTENTS}")
# Write the transformed contents to the output file
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/bundled_program/${_FILE}")
file(WRITE "${OUTPUT_FILE}" "${TRANSFORMED_CONTENTS}")
set(${OUTPUT_VARIABLE} ${OUTPUT_FILE} PARENT_SCOPE)
endfunction()
if(NOT MSVC)
set(BUNDLED_PROGRAMS
"tools/gdal/gdal_contour"
"tools/gdal/gdal_create"
"tools/gdal/gdal_footprint"
"tools/gdal/gdal_grid"
"tools/gdal/gdal_rasterize"
"tools/gdal/gdal_translate"
"tools/gdal/gdal_viewshed"
"tools/gdal/gdaladdo"
"tools/gdal/gdalbuildvrt"
"tools/gdal/gdaldem"
"tools/gdal/gdalenhance"
"tools/gdal/gdalinfo"
"tools/gdal/gdallocationinfo"
"tools/gdal/gdalmanage"
"tools/gdal/gdalmdiminfo"
"tools/gdal/gdalmdimtranslate"
"tools/gdal/gdalsrsinfo"
"tools/gdal/gdaltindex"
"tools/gdal/gdaltransform"
"tools/gdal/gdalwarp"
"tools/gdal/gnmanalyse"
"tools/gdal/gnmmanage"
"tools/gdal/nearblack"
"tools/gdal/ogr2ogr"
"tools/gdal/ogrinfo"
"tools/gdal/ogrlineref"
"tools/gdal/ogrtindex"
"tools/gdal/sozip"
)
set(PYTHON_SCRIPTS
"bin/gdal2tiles"
"bin/gdal2tiles.py"
"bin/gdal2xyz"
"bin/gdal2xyz.py"
"bin/gdal_calc"
"bin/gdal_calc.py"
"bin/gdal_edit"
"bin/gdal_edit.py"
"bin/gdal_fillnodata"
"bin/gdal_fillnodata.py"
"bin/gdal_merge"
"bin/gdal_merge.py"
"bin/gdal_pansharpen"
"bin/gdal_pansharpen.py"
"bin/gdal_polygonize"
"bin/gdal_polygonize.py"
"bin/gdal_proximity"
"bin/gdal_proximity.py"
"bin/gdal_retile"
"bin/gdal_retile.py"
"bin/gdal_sieve"
"bin/gdal_sieve.py"
"bin/gdalattachpct"
"bin/gdalattachpct.py"
"bin/gdalcompare"
"bin/gdalcompare.py"
"bin/gdalmove"
"bin/gdalmove.py"
"bin/ogr_layer_algebra"
"bin/ogr_layer_algebra.py"
"bin/ogrmerge"
"bin/ogrmerge.py"
"bin/pct2rgb"
"bin/pct2rgb.py"
"bin/rgb2pct"
"bin/rgb2pct.py"
)
list(TRANSFORM BUNDLED_PROGRAMS PREPEND "${VCPKG_BASE_DIR}/")
list(TRANSFORM PYTHON_SCRIPTS PREPEND "${VCPKG_BASE_DIR}/")
foreach(FILE ${PYTHON_SCRIPTS})
fixup_shebang("${FILE}" OUTPUT_FILE)
list(APPEND BUNDLED_PROGRAMS "${OUTPUT_FILE}")
endforeach()
install(PROGRAMS ${BUNDLED_PROGRAMS}
DESTINATION "${QGIS_BIN_SUBDIR}")
endif()

View File

@ -11,9 +11,6 @@ endif()
if(WITH_GUI)
list(APPEND VCPKG_MANIFEST_FEATURES "gui")
endif()
if(WITH_ORACLE)
list(APPEND VCPKG_MANIFEST_FEATURES "oracle")
endif()
# Binarycache can only be used on Windows or if mono is available.
find_program(_VCPKG_MONO mono)

View File

@ -37,6 +37,11 @@
#define QSCINTILLA_VERSION_STR "${QSCINTILLA_VERSION_STR}"
#endif
#if defined( __APPLE__ )
//used by Mac to find system or bundle resources relative to amount of bundling
#define QGIS_MACAPP_BUNDLE ${QGIS_MACAPP_BUNDLE}
#endif
#define PYTHON_VERSION "${Python_VERSION}"
#define PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}"
#define PYTHON_VERSION_MINOR "${Python_VERSION_MINOR}"
@ -46,8 +51,6 @@
#define PROJ_VERSION_MINOR ${PROJ_VERSION_MINOR}
#define PROJ_VERSION_PATCH ${PROJ_VERSION_PATCH}
#cmakedefine QGIS_MAC_BUNDLE
#cmakedefine USING_NMAKE
#cmakedefine USING_NINJA

View File

@ -52,7 +52,7 @@ add_custom_target (translations ALL DEPENDS ${QM_FILES} ${MD_FILES})
# first compile sources, then compile translations
if (WITH_DESKTOP)
add_dependencies (translations qgis)
add_dependencies (translations ${QGIS_APP_NAME})
endif()
install (FILES ${QM_FILES}

View File

@ -2,5 +2,5 @@
if (WITH_DESKTOP)
file (GLOB ICONS *.icns)
install (FILES ${ICONS}
DESTINATION ${APP_RESOURCES_DIR})
DESTINATION ${CMAKE_INSTALL_PREFIX}/../Resources)
endif()

Binary file not shown.

Binary file not shown.

BIN
images/icons/mac/qgs.icns Normal file

Binary file not shown.

View File

@ -339,7 +339,6 @@
<file>themes/default/mActionKeyboardShortcuts.svg</file>
<file>themes/default/mActionLabel.svg</file>
<file>themes/default/mActionLabeling.svg</file>
<file>themes/default/mActionLayers.svg</file>
<file>themes/default/mActionLocalCumulativeCutStretch.svg</file>
<file>themes/default/mActionLocalHistogramStretch.svg</file>
<file>themes/default/mActionLockItems.svg</file>

View File

@ -1 +0,0 @@
<svg height="24" viewBox="0 0 6.35 6.35" width="24" xmlns="http://www.w3.org/2000/svg"><g fill="#eeeeec" stroke="#888a85" stroke-linecap="round" stroke-linejoin="round" stroke-width=".265"><path d="m.661 2.778h2.91v2.91h-2.909z"/><path d="m1.72 1.72h2.91v2.91h-2.91z"/><path d="m2.778.661h2.91v2.91h-2.91z"/></g></svg>

Before

Width:  |  Height:  |  Size: 318 B

31
mac/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
# mac bundling must happen at end, so all binaries installed
# and install_names can be adjusted
if (APPLE AND QGIS_MACAPP_BUNDLE GREATER -1)
# for included scripts that set policies (ie OS X bundling)
install (CODE "cmake_policy(SET CMP0011 NEW)")
configure_file (cmake/0vars.cmake.in 0vars.cmake @ONLY)
configure_file (cmake/0qgis.cmake.in 0qgis.cmake @ONLY)
install (SCRIPT ${CMAKE_BINARY_DIR}/mac/0qgis.cmake)
if (QGIS_MACAPP_BUNDLE GREATER 0)
# start with Qt
configure_file (cmake/1qt.cmake.in 1qt.cmake @ONLY)
install (SCRIPT ${CMAKE_BINARY_DIR}/mac/1qt.cmake)
if (QGIS_MACAPP_BUNDLE GREATER 1)
# next - libs
configure_file (cmake/2lib.cmake.in 2lib.cmake @ONLY)
install (SCRIPT ${CMAKE_BINARY_DIR}/mac/2lib.cmake)
if (QGIS_MACAPP_BUNDLE GREATER 2)
# last - frameworks
configure_file (cmake/3fw.cmake.in 3fw.cmake @ONLY)
install (SCRIPT ${CMAKE_BINARY_DIR}/mac/3fw.cmake)
endif()
endif()
endif()
# user bundling
if (QGIS_MACAPP_BUNDLE_USER)
configure_file (${QGIS_MACAPP_BUNDLE_USER} 4user.cmake @ONLY)
install (SCRIPT ${CMAKE_BINARY_DIR}/mac/4user.cmake)
endif()
# tickle app bundle
install (CODE "execute_process(COMMAND touch \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/../../.\")")
endif()

View File

@ -9,39 +9,19 @@
<key>CFBundleIdentifier</key>
<string>org.qgis.qgis3</string>
<key>CFBundleExecutable</key>
<string>@QGIS_APP_NAME@</string>
<string>${QGIS_APP_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>QGIS</string>
<key>CFBundleGetInfoString</key>
<string>@QGIS_APP_NAME@ @COMPLETE_VERSION@-@RELEASE_NAME@ (@SHA@)</string>
<string>${QGIS_APP_NAME} ${COMPLETE_VERSION}-${RELEASE_NAME} (${SHA}), © 2002-2019 QGIS Development Team</string>
<key>CFBundleShortVersionString</key>
<string>@COMPLETE_VERSION@</string>
<string>${COMPLETE_VERSION}</string>
<key>CFBundleVersion</key>
<string>@COMPLETE_VERSION@ (@SHA@)</string>
<string>${COMPLETE_VERSION} (${SHA})</string>
<key>CFBundleIconFile</key>
<string>qgis.icns</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>qgis.icns</string>
</array>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>DarkModeIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>qgis-dark.icns</string>
</array>
</dict>
</dict>
</dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CSResourcesFileMapped</key>
@ -54,7 +34,7 @@
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleTypeIconFile</key>
<string>qgis.icns</string>
<string>qgs.icns</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>qgs</string>
@ -336,11 +316,14 @@
<string>zh_CN</string>
<string>zh_TW</string>
</array>
<key>LSEnvironment</key>
<dict>
<key>QT_AUTO_SCREEN_SCALE_FACTOR</key>
<string>1</string>
</dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>NSLocalNetworkUsageDescription</key>
<string>QGIS needs local network access to communicate with devices on your network.</string>
</dict>
</plist>

31
mac/cmake/0qgis.cmake.in Normal file
View File

@ -0,0 +1,31 @@
# 0qgis - fixup install_names for @loader_path
# ! cmakecache vars not available to external scripts
# so we configure it first to do substitutions
# make sure to use @varname@
# kill boolean warnings
CMAKE_POLICY (SET CMP0012 NEW)
INCLUDE ("@CMAKE_BINARY_DIR@/mac/0vars.cmake")
INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake")
# assume all install_names start with CMAKE_INSTALL_NAME_DIR
# so we don't have to extract it from binaries
# leave main qgis executable and qgis_help with executable_paths
MESSAGE (STATUS "Updating QGIS library paths...")
# inter-library links - do all combos, many will be noops
FOREACH (QL ${QGFWLIST})
GET_INSTALL_NAME ("${QFWDIR}/${QL}.framework/${QL}" ${QL}.framework QQ)
SET (QFW_CHG "${QQ}")
UPDATEQGISPATHS ("${QFW_CHG}" ${QL})
# change id of the framework
IF (NOT @QGIS_MACAPP_INSTALL_DEV@)
EXECUTE_PROCESS(COMMAND install_name_tool -id "${ATEXECUTABLE}/${QGIS_FW_SUBDIR}/${QL}.framework/${QL}" "${QFWDIR}/${QL}.framework/${QL}")
ENDIF ()
ENDFOREACH (QL)
FOREACH (QLIB ${QGLIBLIST})
GET_INSTALL_NAME ("${QLIBDIR}/${QLIB}" ${QLIB} QQ)
SET (QLIB_CHG "${QQ}")
UPDATEQGISPATHS ("${QLIB_CHG}" ${QLIB})
ENDFOREACH (QLIB)

70
mac/cmake/0vars.cmake.in Normal file
View File

@ -0,0 +1,70 @@
# 0vars - redefine cmakecache vars, needed by all other bundling scripts
# ! cmakecache vars not available to external scripts
# so we configure it first to do substitutions
# make sure to use @varname@
# kill boolean warnings
CMAKE_POLICY (SET CMP0012 NEW)
# cmake
SET (CPACK_PACKAGE_VERSION_MAJOR @CPACK_PACKAGE_VERSION_MAJOR@)
SET (CPACK_PACKAGE_VERSION_MINOR @CPACK_PACKAGE_VERSION_MINOR@)
SET (CMAKE_VERBOSE_MAKEFILE "@CMAKE_VERBOSE_MAKEFILE@")
SET (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
SET (CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@")
# Qt5 cmake does not create overall qt prefix var, only individual lib prefixes.
# For simplicity, assume core prefix same as all others
SET (QT_LIBRARY_DIR "@_qt5Core_install_prefix@/lib")
# OS X options
SET (CMAKE_OSX_ARCHITECTURES "@CMAKE_OSX_ARCHITECTURES@")
# QGIS
SET (QGIS_APP_NAME "@QGIS_APP_NAME@")
SET (QGIS_MACAPP_PREFIX "@QGIS_MACAPP_PREFIX@")
SET (QGIS_FW_SUBDIR "@QGIS_FW_SUBDIR@")
SET (QGIS_FW_SUBDIR_REV "@QGIS_FW_SUBDIR_REV@")
SET (QGIS_BIN_SUBDIR "@QGIS_BIN_SUBDIR@")
SET (QGIS_BIN_SUBDIR_REV "@QGIS_BIN_SUBDIR_REV@")
SET (QGIS_CGIBIN_SUBDIR "@QGIS_CGIBIN_SUBDIR@")
SET (QGIS_CGIBIN_SUBDIR_REV "@QGIS_CGIBIN_SUBDIR_REV@")
SET (QGIS_LIB_SUBDIR "@QGIS_LIB_SUBDIR@")
SET (QGIS_LIB_SUBDIR_REV "@QGIS_LIB_SUBDIR_REV@")
SET (QGIS_LIBEXEC_SUBDIR "@QGIS_LIBEXEC_SUBDIR@")
SET (QGIS_LIBEXEC_SUBDIR_REV "@QGIS_LIBEXEC_SUBDIR_REV@")
SET (QGIS_PLUGIN_SUBDIR "@QGIS_PLUGIN_SUBDIR@")
SET (QGIS_PLUGIN_SUBDIR_REV "@QGIS_PLUGIN_SUBDIR_REV@")
SET (QGIS_DATA_SUBDIR "@QGIS_DATA_SUBDIR@")
SET (QGIS_DATA_SUBDIR_REV "@QGIS_DATA_SUBDIR_REV@")
SET (QGIS_SERVER_MODULE_SUBDIR "@QGIS_SERVER_MODULE_SUBDIR@")
# optional components
SET (WITH_GRASS "@WITH_GRASS@")
SET (WITH_SERVER "@WITH_SERVER@")
SET (WITH_POSTGRESQL "@WITH_POSTGRESQL@")
SET (WITH_QSPATIALITE "@WITH_QSPATIALITE@")
# tests
SET (ENABLE_TESTS "@ENABLE_TESTS@")
# Python module search paths
# Allows overriding build variables with PYTHONPATH
# Handles case where resolved symlinked modules may not be where other resolved modules exist, e.g.
# a site-packages directory where all packages/modules are symlinked in (like Homebrew),
# and their respective install prefixes are completely different
# This also handles migration to next-gen sip/PyQt setup where sipconfig and pyqtconfig don't exist
# and the sys.paths used to import the modules dictates how the modules are found
# see: https://github.com/qgis/QGIS/pull/1508
SET (PYTHON_MODULE_PATHS)
STRING(REPLACE ":" ";" _pythonpath "$ENV{PYTHONPATH}")
LIST(APPEND PYTHON_MODULE_PATHS ${_pythonpath})
IF (EXISTS "@PYQT5_MOD_DIR@")
LIST(APPEND PYTHON_MODULE_PATHS "@PYQT5_MOD_DIR@")
ENDIF ()
IF (EXISTS "@SIP_MODULE_DIR@")
LIST(APPEND PYTHON_MODULE_PATHS "@SIP_MODULE_DIR@")
ENDIF ()
IF (EXISTS "@PYTHON_SITE_PACKAGES_SYS@")
LIST(APPEND PYTHON_MODULE_PATHS "@PYTHON_SITE_PACKAGES_SYS@")
ENDIF ()

509
mac/cmake/1qt.cmake.in Normal file
View File

@ -0,0 +1,509 @@
# 1qt - bundle Qt frameworks and PyQt
# ! cmakecache vars not available to external scripts
# so we configure it first to do substitutions
# make sure to use @varname@
# kill boolean warnings
CMAKE_POLICY (SET CMP0012 NEW)
INCLUDE ("@CMAKE_BINARY_DIR@/mac/0vars.cmake")
INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake")
INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/QCAMacros.cmake")
# Qt framework version is major version
SET (QT_FWVER "5")
# build list of Qt frameworks to bundle
# core list, includes dependencies and used by extra plugins
SET (QTLISTQG QtCore QtGui QtWidgets QtNetwork QtXml QtSvg QtConcurrent QtPrintSupport QtSerialPort QtPositioning QtTest QtSql QtDBus)
SET (PYQTLIST Qt QtCore QtGui QtWidgets QtNetwork QtXml QtSvg QtPrintSupport QtPositioning QtSerialPort QtTest QtSql QtDBus)
# QtQuickWidgets appears to be implied direct dep, it needs Quick and Qml,
# whether or not WITH_QUICK specified
SET (QTLISTQG ${QTLISTQG} QtQuickWidgets QtQuick QtQml)
SET (PYQTLIST ${PYQTLIST} QtQuickWidgets QtQuick QtQml)
IF(@WITH_QTWEBKIT@)
SET (QTLISTQG ${QTLISTQG} QtWebKit QtWebKitWidgets QtSensors QtWebChannel QtMultimedia QtMultimediaWidgets QtOpenGL)
SET (PYQTLIST ${PYQTLIST} QtWebKit QtWebKitWidgets QtSensors QtWebChannel QtMultimedia QtMultimediaWidgets QtOpenGL)
ENDIF ()
IF(@WITH_3D@)
SET (QTLISTQG ${QTLISTQG} Qt3DCore Qt3DRender Qt3DInput Qt3DLogic Qt3DExtras QtGamepad)
SET (PYQTLIST ${PYQTLIST} Qt3DCore Qt3DRender Qt3DInput Qt3DLogic Qt3DExtras QtGamepad)
ENDIF ()
# add Qsci.so, if available
IF (@QSCI_FOUND@)
SET (PYQTLIST ${PYQTLIST} Qsci)
ENDIF (@QSCI_FOUND@)
MYMESSAGE ("Qt list: ${QTLISTQG}")
# symlinks when only @executable_path used
EXECUTE_PROCESS (COMMAND ln -sfn ../Frameworks "${QAPPDIR}/")
IF (IS_DIRECTORY "${QLIBDIR}/grass/bin")
EXECUTE_PROCESS (COMMAND ln -sfn ../@QGIS_LIBEXEC_SUBDIR_REV@/@QGIS_FW_SUBDIR@ "${QLIBDIR}/grass/Frameworks")
ENDIF ()
EXECUTE_PROCESS (COMMAND ln -sfn @QGIS_CGIBIN_SUBDIR_REV@/@QGIS_LIB_SUBDIR@ "${QCGIDIR}/lib")
### copy files & strip qt rpath
# Qt frameworks
# Qt5 cmake does not create overall qt prefix var, only individual lib prefixes.
# For simplicity, assume core prefix same as all others.
MESSAGE (STATUS "Copying Qt frameworks...")
EXECUTE_PROCESS (COMMAND mkdir -p "${QFWDIR}")
FOREACH (QFW ${QTLISTQG})
IF (NOT IS_DIRECTORY "${QFWDIR}/${QFW}.framework")
COPY_FRAMEWORK("${QT_LIBRARY_DIR}" ${QFW} "${QFWDIR}")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QFWDIR}/${QFW}.framework/${QFW}")
ENDIF ()
ENDFOREACH (QFW)
# Qt plugins
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../imageformats")
FOREACH (QI qgif;qico;qjpeg;qsvg;qtiff)
IF (NOT EXISTS "${QPLUGDIR}/../imageformats/lib${QI}.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/imageformats/lib${QI}.dylib" "${QPLUGDIR}/../imageformats/lib${QI}.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../imageformats/lib${QI}.dylib")
ENDIF ()
ENDFOREACH (QI)
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../platforms")
FOREACH (QTP cocoa;minimal;offscreen)
IF (NOT EXISTS "${QPLUGDIR}/../platforms/libq${QTP}.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/platforms/libq${QTP}.dylib" "${QPLUGDIR}/../platforms/libq${QTP}.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../platforms/libq${QTP}.dylib")
ENDIF ()
ENDFOREACH (QTP)
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../sqldrivers")
SET (QTLISTSQL ite odbc psql mysql)
# qspatialite driver plugin is part of QGIS build
IF (@WITH_QSPATIALITE@)
LIST(APPEND QTLISTSQL spatialite)
IF (EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
EXECUTE_PROCESS (COMMAND ${CMAKE_COMMAND} -E remove "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
ENDIF ()
ENDIF ()
FOREACH (QSL ${QTLISTSQL})
IF (NOT EXISTS "${QPLUGDIR}/../sqldrivers/libqsql${QSL}.dylib" AND EXISTS "@QT_PLUGINS_DIR@/sqldrivers/libqsql${QSL}.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/sqldrivers/libqsql${QSL}.dylib" "${QPLUGDIR}/../sqldrivers/libqsql${QSL}.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../sqldrivers/libqsql${QSL}.dylib")
ENDIF ()
ENDFOREACH (QSL)
IF (NOT @WITH_QSPATIALITE@ AND EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
EXECUTE_PROCESS (COMMAND ${CMAKE_COMMAND} -E remove "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
ENDIF ()
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../iconengines")
IF (NOT EXISTS "${QPLUGDIR}/../iconengines/libqsvgicon.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/iconengines/libqsvgicon.dylib" "${QPLUGDIR}/../iconengines/libqsvgicon.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../iconengines/libqsvgicon.dylib")
ENDIF ()
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../styles")
IF (NOT EXISTS "${QPLUGDIR}/../styles/libqmacstyle.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/styles/libqmacstyle.dylib" "${QPLUGDIR}/../styles/libqmacstyle.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../styles/libqmacstyle.dylib")
ENDIF ()
# Qwt
STRING (REGEX MATCH "\\.dylib$" QWT_ISLIB "@QWT_LIBRARY@")
STRING (REGEX MATCH "qwt.framework" QWT_ISFW "@QWT_LIBRARY@")
IF (QWT_ISLIB)
# shared libraries
MESSAGE (STATUS "Copying Qwt and updating library paths...")
IF (NOT EXISTS "${QLIBDIR}/libqwt.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QWT_LIBRARY@" "${QLIBDIR}/libqwt.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QLIBDIR}/libqwt.dylib")
ENDIF ()
GET_INSTALL_NAME ("@QWT_LIBRARY@" "libqwt" QWT_CHG)
IF (QWT_CHG)
UPDATEQGISPATHS (${QWT_CHG} libqwt.dylib)
ENDIF (QWT_CHG)
ELSEIF (QWT_ISFW AND EXISTS "@QWT_LIBRARY@")
# framework
MESSAGE (STATUS "Copying Qwt framework and updating library paths...")
STRING(REGEX REPLACE "/qwt.framework.*" "" QWT_PARENT "@QWT_LIBRARY@")
IF (NOT IS_DIRECTORY "${QFWDIR}/qwt.framework")
COPY_FRAMEWORK("${QWT_PARENT}" "qwt" "${QFWDIR}")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QFWDIR}/qwt.framework/qwt")
ENDIF ()
GET_INSTALL_NAME ("${QWT_PARENT}/qwt.framework/qwt" "qwt.framework" QWT_CHG)
IF (QWT_CHG)
UPDATEQGISPATHS (${QWT_CHG} qwt)
ENDIF (QWT_CHG)
ENDIF (QWT_ISLIB)
# QwtPolar
IF (@WITH_DESKTOP@)
IF (@WITH_QWTPOLAR@ AND NOT @WITH_INTERNAL_QWTPOLAR@)
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QWTPOLAR_LIBRARY@")
STRING (REGEX MATCH "qwtpolar.framework" ISFW "@QWTPOLAR_LIBRARY@")
IF (ISLIB)
# shared libraries
MESSAGE (STATUS "Copying QwtPolar and updating library paths...")
IF (NOT EXISTS "${QLIBDIR}/libqwtpolar.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QWT_LIBRARY@" "${QLIBDIR}/libqwtpolar.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QLIBDIR}/libqwtpolar.dylib")
ENDIF ()
GET_INSTALL_NAME ("@QWTPOLAR_LIBRARY@" "libqwtpolar" QWTP_CHG)
IF (QWTP_CHG)
UPDATEQGISPATHS (${QWTP_CHG} libqwtpolar.dylib)
ENDIF (QWTP_CHG)
# update qwt lib in qwtpolar
IF (QWT_CHG)
IF (QWT_ISLIB)
SET (QWT_CHG_TO "${ATLOADER}/libqwt.dylib")
ElSE ()
SET (QWT_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/qwt.framework/qwt")
ENDIF ()
INSTALLNAMETOOL_CHANGE ("${QWT_CHG}" "${QWT_CHG_TO}" "${QLIBDIR}/libqwtpolar.dylib")
ENDIF (QWT_CHG)
ELSEIF (ISFW AND EXISTS "@QWTPOLAR_LIBRARY@")
# framework
MESSAGE (STATUS "Copying QwtPolar framework and updating library paths...")
STRING(REGEX REPLACE "/qwtpolar.framework.*" "" QWTP_PARENT "@QWTPOLAR_LIBRARY@")
IF (NOT IS_DIRECTORY "${QFWDIR}/qwtpolar.framework")
COPY_FRAMEWORK("${QWTP_PARENT}" "qwtpolar" "${QFWDIR}")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QFWDIR}/qwtpolar.framework/qwtpolar")
ENDIF ()
GET_INSTALL_NAME ("${QWTP_PARENT}/qwtpolar.framework/qwtpolar" "qwtpolar.framework" QWTP_CHG)
IF (QWTP_CHG)
UPDATEQGISPATHS (${QWTP_CHG} qwtpolar)
ENDIF (QWTP_CHG)
# update qwt lib in qwtpolar
IF (QWT_CHG)
IF (QWT_ISLIB)
SET (QWT_CHG_TO "${ATLOADER}/../../../${QGIS_FW_SUBDIR_REV}/${QGIS_LIB_SUBDIR}/libqwt.dylib")
ElSE ()
SET (QWT_CHG_TO "${ATLOADER}/../../../qwt.framework/qwt")
ENDIF ()
INSTALLNAMETOOL_CHANGE ("${QWT_CHG}" "${QWT_CHG_TO}" "${QFWDIR}/qwtpolar.framework/qwtpolar")
ENDIF (QWT_CHG)
ENDIF (ISLIB)
ENDIF (@WITH_QWTPOLAR@ AND NOT @WITH_INTERNAL_QWTPOLAR@)
ENDIF (@WITH_DESKTOP@)
# QCA
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QCA_LIBRARY@")
STRING (REGEX MATCH "qca.*.framework" ISFW "@QCA_LIBRARY@")
IF (ISLIB)
# shared libraries
MESSAGE (STATUS "Copying QCA and updating library paths...")
SET (QCA_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/${QGIS_LIB_SUBDIR}/libqca.dylib")
IF (NOT EXISTS "${QLIBDIR}/libqca.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QCA_LIBRARY@" "${QLIBDIR}/libqca.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QLIBDIR}/libqca.dylib")
ENDIF ()
GET_INSTALL_NAME ("@QCA_LIBRARY@" "libqca" QCA_CHG)
IF (QCA_CHG)
UPDATEQGISPATHS (${QCA_CHG} libqca.dylib)
ENDIF ()
ELSEIF (ISFW AND EXISTS "@QCA_LIBRARY@")
# framework
MESSAGE (STATUS "Copying QCA framework and updating library paths...")
SET (QCA_LIBRARY "@QCA_LIBRARY@")
STRING (REGEX MATCH "qca-qt5" _has_long_name "${QCA_LIBRARY}")
IF (_has_long_name)
SET (_qca_libname "qca-qt5")
ELSE ()
SET (_qca_libname "qca")
ENDIF ()
STRING (REGEX MATCH "${_qca_libname}.framework/${_qca_libname}" _has_bin "${QCA_LIBRARY}")
IF (NOT _has_bin)
SET (QCA_LIBRARY "${QCA_LIBRARY}/${_qca_libname}")
ENDIF ()
SET (QCA_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${_qca_libname}.framework/${_qca_libname}")
IF (NOT IS_DIRECTORY "${QFWDIR}/${_qca_libname}.framework")
STRING(REGEX REPLACE "/${_qca_libname}.framework.*" "" QCA_PARENT "@QCA_LIBRARY@")
COPY_FRAMEWORK("${QCA_PARENT}" "${_qca_libname}" "${QFWDIR}")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QFWDIR}/${_qca_libname}.framework/${_qca_libname}")
ENDIF ()
GET_INSTALL_NAME ("${QCA_LIBRARY}" "${_qca_libname}" QCA_CHG)
IF (QCA_CHG)
UPDATEQGISPATHS (${QCA_CHG} ${_qca_libname})
ENDIF ()
ENDIF ()
# copy and relink the plugins
EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../crypto")
FIND_QCA_PLUGIN_DIR (1)
MESSAGE (STATUS "Updating QCA plugins with QCA library path in ${QCA_PLUGIN_DIR} ...")
# don't copy over any unneeded plugins
SET(QCA_PLUGINS logger ossl softstore)
FOREACH (qca_plugin ${QCA_PLUGINS})
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${QCA_PLUGIN_DIR}/crypto/libqca-${qca_plugin}.dylib" "${QPLUGDIR}/../crypto/")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QCA_PLUGIN_DIR}/crypto/libqca-${qca_plugin}.dylib")
IF (QCA_CHG)
INSTALLNAMETOOL_CHANGE ("${QCA_CHG}" "${QCA_CHG_TO}" "${QPLUGDIR}/../crypto/libqca-${qca_plugin}.dylib")
ENDIF ()
ENDFOREACH ()
# QSpatialite Qt plugin
# linked to qca and qgis_core frameworks (see also 2lib.cmake.in)
IF (@WITH_QSPATIALITE@ AND EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
# qca.framework
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
INSTALLNAMETOOL_CHANGE ("${QCA_CHG}" "${QCA_CHG_TO}" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
# qgis_core.framework
GET_INSTALL_NAME ("@QGIS_OUTPUT_DIRECTORY@/lib/qgis_core.framework/qgis_core" qgis_core.framework QGCORE)
SET (QGCORE_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/qgis_core.framework/qgis_core")
INSTALLNAMETOOL_CHANGE ("${QGCORE}" "${QGCORE_CHG_TO}" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
ENDIF ()
# QScintilla2
IF (@QSCINTILLA_LIBRARY@ MATCHES ".*libqscintilla2_qt5.*dylib")
SET (QSCI_LIB "libqscintilla2_qt5")
ELSEIF (@QSCINTILLA_LIBRARY@ MATCHES ".*libqscintilla2.*dylib")
SET (QSCI_LIB "libqscintilla2")
ENDIF ()
IF (QSCI_LIB)
MESSAGE (STATUS "Copying QScintilla2 library and updating library paths...")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QSCINTILLA_LIBRARY@" "${QLIBDIR}/${QSCI_LIB}.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QLIBDIR}/${QSCI_LIB}.dylib")
GET_INSTALL_NAME ("@QSCINTILLA_LIBRARY@" "${QSCI_LIB}" QSCI_CHG)
IF (QSCI_CHG)
UPDATEQGISPATHS (${QSCI_CHG} ${QSCI_LIB}.dylib)
ENDIF (QSCI_CHG)
ENDIF ()
# QtKeychain
IF (@QTKEYCHAIN_LIBRARY@ MATCHES ".*libqt5keychain.dylib")
MESSAGE (STATUS "Copying QtKeychain library and updating library paths...")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QTKEYCHAIN_LIBRARY@" "${QLIBDIR}/libqt5keychain.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QLIBDIR}/libqt5keychain.dylib")
GET_INSTALL_NAME ("@QTKEYCHAIN_LIBRARY@" "libqt5keychain" QTKEY_CHG)
IF (QTKEY_CHG)
UPDATEQGISPATHS (${QTKEY_CHG} libqt5keychain.dylib)
ENDIF (QTKEY_CHG)
ENDIF ()
# Tell user what Python paths are being searched for modules and packages
# see: PYTHON_MODULE_PATHS in 0vars.cmake.in for why not all PyQt-related modules
# can be assumed to exist in symlinked-resolved PyQt or sip module directories
MESSAGE (STATUS "PYTHON_MODULE_PATHS to be searched:")
FOREACH (PYPATH ${PYTHON_MODULE_PATHS})
MESSAGE (STATUS " ${PYPATH}")
ENDFOREACH (PYPATH)
# sip and PyQt
MESSAGE (STATUS "Copying sip...")
PYTHONMODULEDIR("sip.so" SIPMODDIR)
IF (SIPMODDIR)
IF (NOT EXISTS "${QGISPYDIR}/sip.so" AND NOT EXISTS "${QGISPYDIR}/PyQt5/sip.so")
# MYMESSAGE ("ditto ${QARCHS} \"${SIPMODDIR}/sip.so\" \"${QGISPYDIR}/\"")
IF (${SIPMODDIR} MATCHES ".*PyQt5.*")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${SIPMODDIR}/sip.so" "${QGISPYDIR}/PyQt5/")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QGISPYDIR}/PyQt5/sip.so")
ELSE ()
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${SIPMODDIR}/sip.so" "${QGISPYDIR}/")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QGISPYDIR}/sip.so")
ENDIF ()
EXECUTE_PROCESS (COMMAND cp -fp "${SIPMODDIR}/sipconfig.py" "${QGISPYDIR}/")
ENDIF ()
ELSE ()
MESSAGE (STATUS " sip module not found")
ENDIF ()
MESSAGE (STATUS "Copying PyQt...")
EXECUTE_PROCESS (COMMAND mkdir -p "${QGISPYDIR}/PyQt${QT_FWVER}")
FOREACH (PQ ${PYQTLIST})
SET (MODNAME "${PQ}.so")
SET (MODPYI "PyQt${QT_FWVER}/${PQ}.pyi")
SET (MODSUBPATH "PyQt${QT_FWVER}/${MODNAME}")
# search for each module separately, instead of only in first found PyQt directory, since PyQt may
# be installed to its a specific prefix, like with Homebrew, then symlinked into common 'site-packages'
PYTHONMODULEDIR("${MODSUBPATH}" MODDIR)
IF (MODDIR)
IF (NOT EXISTS "${QGISPYDIR}/${MODSUBPATH}")
# MESSAGE (STATUS "ditto ${QARCHS} \"${PYQT5MOD}\" \"${QGISPYDIR}/${MODSUBPATH}\"")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${MODDIR}/${MODSUBPATH}" "${QGISPYDIR}/${MODSUBPATH}")
EXECUTE_PROCESS (COMMAND install_name_tool -delete_rpath "@QT_LIBRARY_DIR@" "${QGISPYDIR}/${MODSUBPATH}")
IF (EXISTS "${MODDIR}/${MODPYI}")
EXECUTE_PROCESS (COMMAND ditto "${MODDIR}/${MODPYI}" "${QGISPYDIR}/${MODPYI}")
ENDIF ()
ENDIF ()
ELSE (MODDIR)
MESSAGE (STATUS " PyQt5 module ${MODNAME} not found")
ENDIF (MODDIR)
UNSET(PYQT5MOD)
ENDFOREACH (PQ)
PYTHONMODULEDIR("PyQt${QT_FWVER}" PYQTMODDIR)
FILE (GLOB PQPYLIST "${PYQTMODDIR}/PyQt${QT_FWVER}/*.py*")
FOREACH (PQPY ${PQPYLIST})
EXECUTE_PROCESS (COMMAND cp -fp "${PQPY}" "${QGISPYDIR}/PyQt${QT_FWVER}/")
ENDFOREACH (PQPY)
EXECUTE_PROCESS (COMMAND cp -RfpL "${PYQTMODDIR}/PyQt${QT_FWVER}/uic" "${QGISPYDIR}/PyQt${QT_FWVER}")
# PyQt utilities
FOREACH (PU pylupdate5;pyrcc5)
IF (NOT EXISTS "${QBINDIR}/${PU}")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@PYQT5_BIN_DIR@/${PU}" "${QBINDIR}/")
ENDIF ()
ENDFOREACH (PU)
IF (NOT EXISTS "${QBINDIR}/pyuic5")
EXECUTE_PROCESS (COMMAND sed -E "s, /.*/PyQt5/uic/pyuic.py, \"\$(/usr/bin/dirname \"\$0\")/../../Resources/python/PyQt5/uic/pyuic.py\"," "@PYQT5_BIN_DIR@/pyuic5"
OUTPUT_VARIABLE PYUIC_CONTENTS)
FILE (WRITE "${QBINDIR}/pyuic4" "${PYUIC_CONTENTS}")
EXECUTE_PROCESS (COMMAND chmod +x "${QBINDIR}/pyuic4")
ENDIF ()
# PyQwt
# only if it's available, not compatible with newer PyQt
PYTHONMODULEDIR("Qwt5/_iqt.so" QWT4MODDIR)
IF (QWT4MODDIR)
MESSAGE (STATUS "Copying PyQwt and updating library paths...")
EXECUTE_PROCESS (COMMAND mkdir -p "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5")
IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/_iqt.so")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${QWT4MODDIR}/Qwt5/_iqt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/")
ENDIF ()
IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/Qwt.so")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${QWT4MODDIR}/Qwt5/Qwt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/")
ENDIF ()
FILE (GLOB PQWPYLIST "${QWT4MODDIR}/Qwt5/*.py")
FOREACH (PQWPY ${PQWPYLIST})
EXECUTE_PROCESS (COMMAND cp -fp "${PQWPY}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/")
ENDFOREACH (PQWPY)
IF (QWT_CHG)
SET (QWT_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/@QGIS_LIB_SUBDIR@/libqwt.dylib")
FOREACH (PW _iqt;Qwt)
INSTALLNAMETOOL_CHANGE ("${QWT_CHG}" "${QWT_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so")
ENDFOREACH (PW)
ENDIF (QWT_CHG)
ENDIF ()
# QScintilla Python module
# should have already been copied with PyQt modules
IF (EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qsci.so")
MESSAGE (STATUS "Updating QScintilla2 Python module library paths...")
GET_INSTALL_NAME ("${QGISPYDIR}/PyQt${QT_FWVER}/Qsci.so" "${QSCI_LIB}" QSCI_CHG)
IF (QSCI_CHG)
SET (QSCI_CHG_TO "${ATEXECUTABLE}/@QGIS_LIB_SUBDIR@/${QSCI_LIB}.dylib")
SET (QSCI_CHG_TO "${ATLOADER}/../../@QGIS_DATA_SUBDIR_REV@/@QGIS_LIB_SUBDIR@/${QSCI_LIB}.dylib")
INSTALLNAMETOOL_CHANGE ("${QSCI_CHG}" "${QSCI_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qsci.so")
ENDIF (QSCI_CHG)
ENDIF ()
# don't load plugins from system-installed Qt
FILE (WRITE "${QAPPDIRC}/Resources/qt.conf" "")
FOREACH (QA ${QGAPPLIST})
FILE (WRITE "${QBINDIR}/${QA}.app/Contents/Resources/qt.conf" "")
ENDFOREACH (QA)
### update lib paths
MESSAGE (STATUS "Updating Qt library paths...")
FOREACH (QFW ${QTLISTQG})
# get install names from installed in case bundled copy already changed
# from a previous install attempt
GET_INSTALL_NAME ("${QT_LIBRARY_DIR}/${QFW}.framework/${QFW}" ${QFW}.framework QQ)
SET (QFW_CHG "${QQ}")
# qgis stuff
UPDATEQGISPATHS ("${QFW_CHG}" ${QFW})
SET (LIBPOST "${QFW}.framework/${QFW}")
# Qwt
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QWT_LIBRARY@")
STRING (REGEX MATCH "qwt.framework" ISFW "@QWT_LIBRARY@")
IF (ISLIB)
SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqwt.dylib")
ELSEIF (ISFW AND EXISTS "${QFWDIR}/qwt.framework/qwt")
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/qwt.framework/qwt")
ENDIF (ISLIB)
# qtkeychain
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QTKEYCHAIN_LIBRARY@")
STRING (REGEX MATCH "qt5keychain.framework" ISFW "@QTKEYCHAIN_LIBRARY@")
IF (ISLIB)
SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqt5keychain.dylib")
ELSEIF (ISFW AND EXISTS "${QFWDIR}/qt5keychain.framework/qt5keychain")
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/qt5keychain.framework/qt5keychain")
ENDIF (ISLIB)
# QwtPolar
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QWTPOLAR_LIBRARY@")
STRING (REGEX MATCH "qwtpolar.framework" ISFW "@QWTPOLAR_LIBRARY@")
IF (ISLIB)
SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqwtpolar.dylib")
ELSEIF (ISFW AND EXISTS "${QFWDIR}/qwtpolar.framework/qwtpolar")
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/qwtpolar.framework/qwtpolar")
ENDIF (ISLIB)
# QCA
STRING (REGEX MATCH "\\.dylib$" ISLIB "@QCA_LIBRARY@")
STRING (REGEX MATCH "${_qca_libname}.framework" ISFW "@QCA_LIBRARY@")
IF (ISLIB)
SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqca.dylib")
ELSEIF (ISFW AND EXISTS "${QFWDIR}/${_qca_libname}.framework/${_qca_libname}")
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/${_qca_libname}.framework/${_qca_libname}")
ENDIF (ISLIB)
# QScintilla2
SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/${QSCI_LIB}.dylib")
# qt plugs
SET (QFW_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}")
# qca plugins
FOREACH (qca_plugin ${QCA_PLUGINS})
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../crypto/libqca-${qca_plugin}.dylib")
ENDFOREACH ()
FOREACH (QI qgif;qico;qjpeg;qsvg;qtiff)
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../imageformats/lib${QI}.dylib")
ENDFOREACH (QI)
FOREACH (QP cocoa;minimal;offscreen)
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../platforms/libq${QP}.dylib")
ENDFOREACH (QP)
FOREACH (QSL ${QTLISTSQL})
IF (EXISTS "${QPLUGDIR}/../sqldrivers/libqsql${QSL}.dylib")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../sqldrivers/libqsql${QSL}.dylib")
ENDIF ()
ENDFOREACH (QSL)
IF (@WITH_QSPATIALITE@ AND EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
EXECUTE_PROCESS (COMMAND install_name_tool -id "libqsqlspatialite.dylib" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
ENDIF ()
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../iconengines/libqsvgicon.dylib")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../phonon_backend/libphonon_qt7.dylib")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../styles/libqmacstyle.dylib")
# quick plugin
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QAPPDIR}/qml/QgsQuick/libqgis_quick_plugin.dylib")
# qt fw
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
FOREACH (QF ${QTLISTQG})
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/${QF}.framework/${QF}")
ENDFOREACH (QF)
# PyQt (includes QScintilla2 module)
SET (QFW_CHG_TO "${ATLOADER}/../../@QGIS_DATA_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}")
FOREACH (PQ ${PYQTLIST})
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so")
ENDFOREACH (PQ)
# PyQwt
SET (QFW_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}")
FOREACH (PW _iqt;Qwt)
IF (EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so")
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so")
ENDIF ()
ENDFOREACH (PW)
# bin - PyQt utils
SET (QFW_CHG_TO "${ATEXECUTABLE}/@QGIS_BIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}")
FOREACH (PB pylupdate4;pyrcc4)
INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QBINDIR}/${PB}")
ENDFOREACH (PB)
ENDFOREACH (QFW)

57
mac/cmake/2lib.cmake.in Normal file
View File

@ -0,0 +1,57 @@
# 2lib - bundle shared libraries (but not standard frameworks)
# ! cmakecache vars not available to external scripts
# so we configure it first to do substitutions
# make sure to use @varname@
# for now, just libs not available as frameworks
# libpq
# libfcgi (non-system)
# kill boolean warnings
CMAKE_POLICY (SET CMP0012 NEW)
INCLUDE ("@CMAKE_BINARY_DIR@/mac/0vars.cmake")
INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake")
# Postgres
IF ("@POSTGRES_LIBRARY@" MATCHES ".*libpq.dylib")
MESSAGE (STATUS "Copying libpq and updating library paths...")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@POSTGRES_LIBRARY@" "${QLIBDIR}/libpq.dylib")
GET_INSTALL_NAME ("@POSTGRES_LIBRARY@" "libpq" PQLIB)
UPDATEQGISPATHS (${PQLIB} libpq.dylib)
# may have been built with libintl
GET_INSTALL_NAME ("@POSTGRES_LIBRARY@" "libintl" INTLLIB)
IF (INTLLIB)
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${INTLLIB}" "${QLIBDIR}/libintl.dylib")
SET (LIB_CHG_TO "${ATEXECUTABLE}/@QGIS_LIB_SUBDIR@/libintl.dylib")
SET (LIB_CHG_TO "${ATLOADER}/libintl.dylib")
INSTALLNAMETOOL_CHANGE ("${INTLLIB}" "${LIB_CHG_TO}" "${QLIBDIR}/libpq.dylib")
ENDIF (INTLLIB)
IF (EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlpsql.dylib")
FILE (RELATIVE_PATH _relpath "${QPLUGDIR}/../sqldrivers" "${QLIBDIR}/libpq.dylib")
INSTALLNAMETOOL_CHANGE ("${PQLIB}" "${ATLOADER}/${_relpath}" "${QPLUGDIR}/../sqldrivers/libqsqlpsql.dylib")
ENDIF ()
ENDIF ()
# libspatialindex
IF ("@SPATIALINDEX_LIBRARY@" MATCHES ".*libspatialindex.dylib")
MESSAGE (STATUS "Copying libspatialindex and updating library paths...")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@SPATIALINDEX_LIBRARY@" "${QLIBDIR}/libspatialindex.dylib")
GET_INSTALL_NAME ("@SPATIALINDEX_LIBRARY@" "libspatialindex" SPILIB)
UPDATEQGISPATHS (${SPILIB} libspatialindex.dylib)
IF (@WITH_QSPATIALITE@ AND EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
FILE (RELATIVE_PATH _relpath "${QPLUGDIR}/../sqldrivers" "${QLIBDIR}/libspatialindex.dylib")
INSTALLNAMETOOL_CHANGE ("${SPILIB}" "${ATLOADER}/${_relpath}" "${QPLUGDIR}/../sqldrivers/libqsqlspatialite.dylib")
ENDIF ()
ENDIF ()
# libfcgi (non-system)
IF ("@FCGI_LIBRARY@" MATCHES ".*libfcgi.dylib" AND NOT "@FCGI_LIBRARY@" MATCHES "/usr/lib/.*")
MESSAGE (STATUS "Copying libfcgi and updating library paths...")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@FCGI_LIBRARY@" "${QLIBDIR}/libfcgi.dylib")
GET_INSTALL_NAME ("@FCGI_LIBRARY@" "libfcgi" FCGILIB)
UPDATEQGISPATHS (${FCGILIB} libfcgi.dylib)
ENDIF ()

15
mac/cmake/3fw.cmake.in Normal file
View File

@ -0,0 +1,15 @@
# 3fw - bundle standard frameworks
# ! cmakecache vars not available to external scripts
# so we configure it first to do substitutions
# make sure to use @varname@
MESSAGE (STATUS "Bundling other frameworks is not functional yet, skipping...")
# kill boolean warnings
CMAKE_POLICY (SET CMP0012 NEW)
INCLUDE ("@CMAKE_BINARY_DIR@/mac/0vars.cmake")
INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake")
#

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_FRAMEWORK_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_FRAMEWORK_NAME} ${COMPLETE_VERSION}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_FRAMEWORK_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${MACOSX_FRAMEWORK_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_FRAMEWORK_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_FRAMEWORK_NAME} ${COMPLETE_VERSION}</string>
</dict>
</plist>

21
mac/readme.txt Normal file
View File

@ -0,0 +1,21 @@
Mac Notes
*********
The 'cmake' folder scripts handle bundling dependent libraries in the QGIS
application package and fixing up the library paths. It is automatic during
installation. There are 2 levels currently, specified with the cmake config
option QGIS_MACAPP_BUNDLE, and one that always occurs:
-1 = do not run bundle install scrips
0 = (default) fixup the library paths for all QGIS libraries if @loader_path
is available in the system (OS X 10.5+)
1 = bundle Qt, PyQt, PyQwt and OSG/osgEarth
2 = additionally, bundle libraries, but not frameworks
A third level that is not finished will additionally bundle frameworks.
This would create the "standalone" QGIS.
There is also a configure option to set a user bundle script,
QGIS_MACAPP_BUNDLE_USER. This specifies the path to a cmake bundle script
similar to the built-in bundle scripts for the defined levels. This script is
always run independent of and after the QGIS_MACAPP_BUNDLE level specified.

View File

@ -1,31 +0,0 @@
if(NOT "$ENV{MACOS_CODE_SIGN_IDENTITY}" STREQUAL "")
# -appstore-compliant will strip away odbc, psql and webengine plugins
execute_process(COMMAND "@PYMACDEPLOYQT_EXECUTABLE@" @QGIS_APP_NAME@.app -codesign=${MACOS_CODE_SIGN_IDENTITY} -sign-for-notarization=${MACOS_CODE_SIGN_IDENTITY}
WORKING_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}
COMMAND_ERROR_IS_FATAL ANY
)
if (@CREATE_DMG@)
execute_process(COMMAND create-dmg --volname "@QGIS_APP_NAME@ Installer" --hide-extension @QGIS_APP_NAME@.app --volicon "@CMAKE_SOURCE_DIR@/images/icons/mac/qgis.icns" --background "@CMAKE_SOURCE_DIR@/platform/macos/installer_background.png" --window-pos 200 120 --window-size 512 384 --icon-size 100 --icon "@QGIS_APP_NAME@.app" 130 160 --app-drop-link 400 155 --codesign "${MACOS_CODE_SIGN_IDENTITY}" @CMAKE_BINARY_DIR@/@QGIS_APP_NAME@-Installer.dmg ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app
RESULT_VARIABLE CREATE_DMG_FAILURE)
if(CREATE_DMG_FAILURE)
message(STATUS "Creating dmg failed.")
endif()
endif()
else()
# -appstore-compliant will strip away odbc, psql and webengine plugins
execute_process(COMMAND "@PYMACDEPLOYQT_EXECUTABLE@" "@QGIS_APP_NAME@.app"
WORKING_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}
COMMAND_ERROR_IS_FATAL ANY
)
if (@CREATE_DMG@)
execute_process(COMMAND create-dmg --volname "@QGIS_APP_NAME@ Installer" --hide-extension @QGIS_APP_NAME@.app --volicon "@CMAKE_SOURCE_DIR@/images/icons/mac/qgis.icns" --background "@CMAKE_SOURCE_DIR@/platform/macos/installer_background.png" --window-pos 200 120 --window-size 512 384 --icon-size 100 --icon "@QGIS_APP_NAME@.app" 130 160 --app-drop-link 400 155 @CMAKE_BINARY_DIR@/@QGIS_APP_NAME@-Installer.dmg ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app
RESULT_VARIABLE CREATE_DMG_FAILURE)
if(CREATE_DMG_FAILURE)
message(STATUS "Creating dmg failed.")
endif()
endif()
endif()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

View File

@ -1,401 +0,0 @@
#!/usr/bin/env python3
import argparse
import os
import shutil
import subprocess
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
from typing import Dict, List, Set, Tuple
# System paths that should be excluded from copying
SYSTEM_PATHS = [
"/usr/lib",
"/System/Library",
"/Library/Frameworks",
]
@dataclass
class Library:
path: str
install_name: str
dependencies: list[str]
rpaths: list[str]
@lru_cache(maxsize=None)
def get_macho_info(path: str) -> bytes:
"""Run otool -l and cache the output."""
result = subprocess.run(["otool", "-l", path], capture_output=True, check=True)
return result.stdout
def parse_macho_info(path: str) -> Library:
"""Parse otool -l output to extract all needed information."""
output = get_macho_info(path).decode("utf-8").split("\n")
install_name = path
rpaths = []
dependencies = []
i = 0
while i < len(output):
line = output[i].strip()
# Look for load command type
if "cmd LC_" not in line:
i += 1
continue
cmd_type = line.split()[-1]
if cmd_type == "LC_ID_DYLIB":
# Next line is cmdsize, name is in the line after
if i + 2 < len(output):
name_line = output[i + 2].strip()
if name_line.startswith("name"):
install_name = name_line.split()[1]
elif cmd_type == "LC_LOAD_DYLIB" or cmd_type == "LC_LOAD_WEAK_DYLIB":
# Next line is cmdsize, name is in the line after
if i + 2 < len(output):
name_line = output[i + 2].strip()
if name_line.startswith("name"):
dep_path = name_line.split()[1]
if dep_path != install_name:
dependencies.append(dep_path)
elif cmd_type == "LC_RPATH":
# Next line is cmdsize, path is in the line after
if i + 2 < len(output):
path_line = output[i + 2].strip()
if path_line.startswith("path"):
rpaths.append(path_line.split()[1])
i += 1
return Library(path, install_name, dependencies, rpaths)
def is_system_path(path: str) -> bool:
"""Check if the path is a system path that should be excluded."""
return any(path.startswith(sys_path) for sys_path in SYSTEM_PATHS)
def find_library(lib_name: str, search_paths: list[str]) -> str:
"""Find library in search paths."""
for path in search_paths:
full_path = os.path.join(path, lib_name)
if os.path.exists(full_path):
return full_path
return ""
def resolve_at_path(dep_path: str, binary_path: str, rpaths: list[str]) -> str:
"""
Resolve a path that starts with @rpath, @executable_path, or @loader_path
Returns resolved absolute path or empty string if not found
"""
if dep_path.startswith("@rpath/"):
lib_name = dep_path[len("@rpath/") :]
# Try all rpaths
for rpath in rpaths:
# Handle nested @ paths in rpaths
if rpath.startswith("@"):
rpath = resolve_at_path(rpath, binary_path, [])
if not rpath:
continue
full_path = os.path.join(rpath, lib_name)
if os.path.exists(full_path):
return full_path
elif dep_path.startswith("@executable_path/"):
lib_name = dep_path[len("@executable_path/") :]
exe_dir = os.path.dirname(binary_path)
full_path = os.path.join(exe_dir, lib_name)
if os.path.exists(full_path):
return full_path
elif dep_path.startswith("@loader_path/"):
lib_name = dep_path[len("@loader_path/") :]
loader_dir = os.path.dirname(binary_path)
full_path = os.path.join(loader_dir, lib_name)
if os.path.exists(full_path):
return full_path
return ""
def collect_dependencies(
binary_path: str, lib_dirs: list[str], processed: set[str]
) -> dict[str, Library]:
"""Recursively collect all dependencies for a binary."""
result = {}
search_paths = lib_dirs.copy()
def process_binary(path: str) -> None:
if path in processed:
return
processed.add(path)
real_path, _ = resolve_symlink(path)
lib_info = parse_macho_info(real_path)
result[path] = lib_info
# Add library's directory to search paths if it's not a system path
lib_dir = os.path.dirname(real_path)
if lib_dir not in search_paths and not is_system_path(lib_dir):
search_paths.append(lib_dir)
# Process dependencies
for dep in lib_info.dependencies:
if dep.startswith("@"):
# If we couldn't resolve it earlier, try again with updated search paths
resolved_path = resolve_at_path(dep, path, lib_info.rpaths)
if resolved_path:
dep = resolved_path
if not os.path.isabs(dep):
dep = find_library(os.path.basename(dep), search_paths)
if dep and os.path.exists(dep):
process_binary(dep)
process_binary(binary_path)
return result
def resolve_symlink(path: str) -> tuple[str, list[str]]:
"""
Resolve a symlink chain to its final destination and return the real file path
along with the chain of symlinks that led to it.
"""
symlink_chain = []
current_path = path
while os.path.islink(current_path):
symlink_chain.append(os.path.basename(current_path))
current_path = os.path.realpath(current_path)
return current_path, symlink_chain
def is_macho(filepath: str) -> bool:
"""
Checks if a file is a Mach-O binary by reading the first 4 bytes.
Args:
filepath: Path to the file to check
Returns:
True if it is a Mach-O file
"""
# Mach-O magic numbers
MAGIC_64 = 0xCFFAEDFE # 64-bit mach-o
MAGIC_32 = 0xCEFAEDFE # 32-bit mach-o
try:
# Open file in binary mode and read first 4 bytes
with open(filepath, "rb") as f:
magic = int.from_bytes(f.read(4), byteorder="big")
if magic in (MAGIC_64, MAGIC_32):
return True
else:
return False
except OSError:
return False
def handle_resources_binaries(app_bundle: str) -> None:
"""
Move Mach-O files from Contents/Resources to Contents/PlugIns/_Resources
and replace them with symlinks.
"""
resources_dir = os.path.join(app_bundle, "Contents", "Resources")
plugins_resources_dir = os.path.join(
app_bundle, "Contents", "PlugIns", "_Resources"
)
if not os.path.exists(resources_dir):
return
# Find all Mach-O files in Resources
for root, _, files in os.walk(resources_dir):
for file in files:
path = os.path.join(root, file)
try:
if is_macho(file):
# Calculate relative path from Resources root
rel_path = os.path.relpath(path, resources_dir)
new_path = os.path.join(plugins_resources_dir, rel_path)
# Create directory structure in PlugIns/_Resources
os.makedirs(os.path.dirname(new_path), exist_ok=True)
# Move the file and create symlink
shutil.move(path, new_path)
relative_target = os.path.relpath(new_path, os.path.dirname(path))
os.symlink(relative_target, path)
except subprocess.CalledProcessError:
continue
def deploy_libraries(app_bundle: str, lib_dirs: list[str]) -> None:
"""Deploy all libraries to the app bundle."""
frameworks_dir = os.path.join(app_bundle, "Contents", "Frameworks")
os.makedirs(frameworks_dir, exist_ok=True)
print("Handle resources binaries")
# Handle Resources binaries first
handle_resources_binaries(app_bundle)
print("Handle main binaries")
# Find all binaries in the app bundle
binaries = []
for root, _, files in os.walk(app_bundle):
for file in files:
path = os.path.join(root, file)
try:
if not os.path.islink(path) and is_macho(path):
binaries.append(path)
except subprocess.CalledProcessError:
continue
processed_libs = set()
all_dependencies = {}
# Collect all dependencies
for binary in binaries:
print(f"Analyzing {binary}")
deps = collect_dependencies(binary, lib_dirs, processed_libs)
all_dependencies.update(deps)
# Copy libraries and prepare install_name_tool commands
commands = {} # path -> list of changes
lib_mapping = {} # old_install_name -> new_install_name
# First pass: copy libraries and record their new install names
for lib_path, lib_info in all_dependencies.items():
if lib_path.startswith(app_bundle):
continue
# Skip system libraries
if is_system_path(lib_path):
continue
# Resolve symlinks to get real file
real_lib_path, symlink_chain = resolve_symlink(lib_path)
# Skip if the real file is in a system path
if is_system_path(real_lib_path):
continue
lib_name = os.path.basename(real_lib_path)
new_path = os.path.join(frameworks_dir, lib_name)
new_install_name = f"@rpath/{lib_name}"
# Record the mapping from old install name to new install name
lib_mapping[lib_info.install_name] = new_install_name
# Copy the real file if not already present
if not os.path.exists(new_path):
shutil.copy2(real_lib_path, new_path)
# Recreate symlink chain
current_name = lib_name
for link_name in reversed(symlink_chain):
link_path = os.path.join(frameworks_dir, link_name)
if not os.path.exists(link_path):
os.symlink(current_name, link_path)
current_name = link_name
# Prepare commands for the library itself
if new_path not in commands:
commands[new_path] = []
# Set its own install name
commands[new_path].append(("-id", new_install_name))
# Second pass: update each binary's direct dependencies
for binary_path, lib_info in all_dependencies.items():
if binary_path not in commands:
commands[binary_path] = []
# Update only the direct dependencies of this binary
for dep in lib_info.dependencies:
if dep in lib_mapping:
commands[binary_path].append(("-change", dep, lib_mapping[dep]))
frameworks_dir = os.path.join(app_bundle, "Contents", "Frameworks")
def calculate_relative_frameworks_path(binary_path: str) -> str:
"""Calculate relative path from binary to Frameworks directory."""
binary_dir = os.path.dirname(binary_path)
rel_path = os.path.relpath(frameworks_dir, binary_dir)
return rel_path
# Set @loader_path/../Frameworks as the only rpath for all binaries
for binary in binaries:
if binary not in commands:
commands[binary] = []
# Get existing rpaths
lib_info = parse_macho_info(binary)
# Delete absolute rpaths
for rpath in lib_info.rpaths:
if rpath.startswith("/"):
commands[binary].append(("-delete_rpath", rpath))
# Add proper search path for all executables
rel_frameworks_path = calculate_relative_frameworks_path(binary)
new_path = f"@loader_path/{rel_frameworks_path}"
if (
binary.startswith(f"{app_bundle}/Contents/MacOS")
and new_path not in lib_info.rpaths
):
commands[binary].append(("-add_rpath", new_path))
# Execute install_name_tool commands
for path, changes in commands.items():
print(f"Changing {path}")
cmd = ["install_name_tool"]
if not changes:
continue
print(f" {changes}")
for command_tuple in changes:
cmd.extend(command_tuple)
print(f"Executing {cmd} {path}")
try:
result = subprocess.run(
cmd + [path], check=True, capture_output=True, text=True
)
print(result.stdout)
print(result.stderr)
except subprocess.CalledProcessError as e:
print(f"Command failed with exit code {e.returncode}")
print("stdout:")
print(e.stdout)
print("stderr:")
print(e.stderr)
raise
def main():
parser = argparse.ArgumentParser(description="Enhanced macdeployqt implementation")
parser.add_argument("app_bundle", help="Path to the app bundle")
parser.add_argument(
"--libdir",
action="append",
default=[],
help="Additional library search directories",
)
args = parser.parse_args()
lib_dirs = args.libdir + [os.path.join(args.app_bundle, "Contents", "Frameworks")]
deploy_libraries(args.app_bundle, lib_dirs)
if __name__ == "__main__":
main()

View File

@ -1,6 +0,0 @@
#!/bin/bash
# This is a wrapper for python, to launch python with the proper PYTHONHOME set
# to make it relocatable.
BASEDIR="$(cd "$(dirname "$0")" && pwd)"
export PYTHONHOME="${BASEDIR}/../Frameworks"
exec ${BASEDIR}/@PYTHON_EXECUTABLE@ "$@"

View File

@ -62,7 +62,7 @@ Returns intensity of the light
Sets intensity of the light
%End
bool operator==( const QgsDirectionalLightSettings &other ) const;
bool operator==( const QgsDirectionalLightSettings &other );
};

View File

@ -95,7 +95,7 @@ Returns quadratic attenuation (A_2)
Sets quadratic attenuation (A_2)
%End
bool operator==( const QgsPointLightSettings &other ) const;
bool operator==( const QgsPointLightSettings &other );
};

View File

@ -153,7 +153,7 @@ pointing towards north. The angle should range from 0 to 360.
%Docstring
Writes camera configuration to the given DOM element
%End
void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
void readXml( const QDomElement &elem );
%Docstring
Reads camera configuration from the given DOM element
%End

View File

@ -91,7 +91,7 @@ ELSE()
SET(BINDING_FILES_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF()
set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis)
set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis)
# core module
file(GLOB_RECURSE sip_files_core ${BINDING_FILES_ROOT_DIR}/core/*.sip ${BINDING_FILES_ROOT_DIR}/core/*.sip.in)

View File

@ -1,4 +1,4 @@
set (QGIS_PYQT_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis/PyQt)
set (QGIS_PYQT_DIR ${Python_SITEARCH}/qgis/PyQt)
set(PYQT_COMPAT_FILES
__init__.py

View File

@ -62,7 +62,7 @@ Returns intensity of the light
Sets intensity of the light
%End
bool operator==( const QgsDirectionalLightSettings &other ) const;
bool operator==( const QgsDirectionalLightSettings &other );
};

View File

@ -95,7 +95,7 @@ Returns quadratic attenuation (A_2)
Sets quadratic attenuation (A_2)
%End
bool operator==( const QgsPointLightSettings &other ) const;
bool operator==( const QgsPointLightSettings &other );
};

View File

@ -153,7 +153,7 @@ pointing towards north. The angle should range from 0 to 360.
%Docstring
Writes camera configuration to the given DOM element
%End
void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
void readXml( const QDomElement &elem );
%Docstring
Reads camera configuration from the given DOM element
%End

View File

@ -10135,9 +10135,6 @@ QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks = Qgis.LayoutRenderFlag.AlwaysUs
QgsLayoutRenderContext.Flag.FlagAlwaysUseGlobalMasks = Qgis.LayoutRenderFlag.AlwaysUseGlobalMasks
QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks.is_monkey_patched = True
QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks.__doc__ = "When applying clipping paths for selective masking, always use global (\"entire map\") paths, instead of calculating local clipping paths per rendered feature. This results in considerably more complex layout exports in all current Qt versions. This flag only applies to vector layout exports. \n.. versionadded:: 3.38"
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature = Qgis.LayoutRenderFlag.LimitCoverageLayerRenderToCurrentFeature
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature.is_monkey_patched = True
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature.__doc__ = "Limit coverage layer rendering to the current atlas feature. \n.. versionadded:: 4.0"
Qgis.LayoutRenderFlag.__doc__ = """Flags for controlling how a layout is rendered.
.. note::
@ -10203,10 +10200,6 @@ Qgis.LayoutRenderFlag.__doc__ = """Flags for controlling how a layout is rendere
Available as ``QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks`` in older QGIS releases.
* ``LimitCoverageLayerRenderToCurrentFeature``: Limit coverage layer rendering to the current atlas feature.
.. versionadded:: 4.0
"""
# --
@ -11505,10 +11498,6 @@ Qgis.MouseHandlesAction.ResizeLeftUp.__doc__ = "Resize left up (Top left handle)
Qgis.MouseHandlesAction.ResizeRightUp.__doc__ = "Resize right up (Top right handle)"
Qgis.MouseHandlesAction.ResizeLeftDown.__doc__ = "Resize left down (Bottom left handle)"
Qgis.MouseHandlesAction.ResizeRightDown.__doc__ = "Resize right down (Bottom right handle)"
Qgis.MouseHandlesAction.RotateTopLeft.__doc__ = "Rotate from top left handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateTopRight.__doc__ = "Rotate from top right handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateBottomLeft.__doc__ = "Rotate from bottom left handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateBottomRight.__doc__ = "Rotate right bottom right handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.SelectItem.__doc__ = "Select item"
Qgis.MouseHandlesAction.NoAction.__doc__ = "No action"
Qgis.MouseHandlesAction.__doc__ = """Action to be performed by the mouse handles
@ -11524,22 +11513,6 @@ Qgis.MouseHandlesAction.__doc__ = """Action to be performed by the mouse handles
* ``ResizeRightUp``: Resize right up (Top right handle)
* ``ResizeLeftDown``: Resize left down (Bottom left handle)
* ``ResizeRightDown``: Resize right down (Bottom right handle)
* ``RotateTopLeft``: Rotate from top left handle.
.. versionadded:: 4.0
* ``RotateTopRight``: Rotate from top right handle.
.. versionadded:: 4.0
* ``RotateBottomLeft``: Rotate from bottom left handle.
.. versionadded:: 4.0
* ``RotateBottomRight``: Rotate right bottom right handle.
.. versionadded:: 4.0
* ``SelectItem``: Select item
* ``NoAction``: No action

View File

@ -1,5 +0,0 @@
# The following has been generated automatically from src/core/qgsfeatureexpressionfilterprovider.h
try:
QgsFeatureExpressionFilterProvider.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,6 +1,5 @@
# The following has been generated automatically from src/core/qgsfeaturefilterprovider.h
try:
QgsFeatureFilterProvider.__virtual_methods__ = ['isFilterThreadSafe', 'filterFeatures']
QgsFeatureFilterProvider.__abstract_methods__ = ['layerAttributes', 'clone']
QgsFeatureFilterProvider.__abstract_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,5 +0,0 @@
# The following has been generated automatically from src/core/qgsgroupedfeaturefilterprovider.h
try:
QgsGroupedFeatureFilterProvider.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -37,26 +37,6 @@ QgsMapLayer.FlagTrustLayerMetadata = QgsMapLayer.ReadFlag.FlagTrustLayerMetadata
QgsMapLayer.FlagReadExtentFromXml = QgsMapLayer.ReadFlag.FlagReadExtentFromXml
QgsMapLayer.FlagForceReadOnly = QgsMapLayer.ReadFlag.FlagForceReadOnly
QgsMapLayer.ReadFlags = lambda flags=0: QgsMapLayer.ReadFlag(flags)
# monkey patching scoped based enum
QgsMapLayer.SaveStyleResult.Success.__doc__ = "Both QML and SLD formats were successfully written to the database."
QgsMapLayer.SaveStyleResult.QmlGenerationFailed.__doc__ = "Generation of the QML failed, and was not written to the database."
QgsMapLayer.SaveStyleResult.SldGenerationFailed.__doc__ = "Generation of the SLD failed, and was not written to the database."
QgsMapLayer.SaveStyleResult.DatabaseWriteFailed.__doc__ = "An error occurred when attempting to write to the database."
QgsMapLayer.SaveStyleResult.__doc__ = """Results of saving styles to database.
.. versionadded:: 4.0
* ``Success``: Both QML and SLD formats were successfully written to the database.
* ``QmlGenerationFailed``: Generation of the QML failed, and was not written to the database.
* ``SldGenerationFailed``: Generation of the SLD failed, and was not written to the database.
* ``DatabaseWriteFailed``: An error occurred when attempting to write to the database.
"""
# --
QgsMapLayer.SaveStyleResult.baseClass = QgsMapLayer
QgsMapLayer.SaveStyleResults = lambda flags=0: QgsMapLayer.SaveStyleResult(flags)
QgsMapLayer.SaveStyleResults.baseClass = QgsMapLayer
SaveStyleResults = QgsMapLayer # dirty hack since SIP seems to introduce the flags in module
from enum import Enum

View File

@ -16,9 +16,7 @@
typedef QVector<QgsPointXY> QgsPolylineXY;
typedef QVector<QgsPoint> QgsPolyline;
typedef QVector<QVector< QgsPoint >> QgsMultiPolyline;
typedef QgsPointSequence QgsPolyline;
typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;

View File

@ -73,26 +73,6 @@ Sets whether the coverage layer should be hidden in map items in the
layouts.
.. seealso:: :py:func:`hideCoverage`
%End
bool limitCoverageLayerRenderToCurrentFeature() const;
%Docstring
Returns ``True`` if the atlas is set to limit rendering on the coverage
layer to the current feature.
.. seealso:: :py:func:`setHideCoverage`
.. versionadded:: 4.0
%End
void setLimitCoverageLayerRenderToCurrentFeature( bool limit );
%Docstring
Sets whether the rendering of the coverage layer should be limited to
the current feature.
.. seealso:: :py:func:`hideCoverage`
.. versionadded:: 4.0
%End
QString filenameExpression() const;

View File

@ -2912,7 +2912,6 @@ The development version
LosslessImageRendering,
SynchronousLegendGraphics,
AlwaysUseGlobalMasks,
LimitCoverageLayerRenderToCurrentFeature,
};
typedef QFlags<Qgis::LayoutRenderFlag> LayoutRenderFlags;
@ -3347,10 +3346,6 @@ The development version
ResizeRightUp,
ResizeLeftDown,
ResizeRightDown,
RotateTopLeft,
RotateTopRight,
RotateBottomLeft,
RotateBottomRight,
SelectItem,
NoAction
};

View File

@ -1,57 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeatureexpressionfilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureExpressionFilterProvider : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgsfeatureexpressionfilterprovider.h"
%End
public:
QgsFeatureExpressionFilterProvider();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated/;
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureExpressionFilterProvider *clone() const /Factory/;
void setFilter( const QString &layerId, const QgsExpression &expression );
%Docstring
Set a filter for the given layer.
:param layerId: the layer to filter
:param expression: the filter expression
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeatureexpressionfilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -1,93 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureFilter : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
%End
%TypeHeaderCode
#include "qgsfeaturefilter.h"
%End
public:
QgsFeatureFilter();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layerId: the layer ID to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
void setFilter( const QgsVectorLayer *layer, const QgsExpression &expression ) /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Set a filter for the given layer.
:param layer: the layer to filter
:param expression: the filter expression
.. deprecated:: 4.0
Use the layer ID variant.
%End
void setFilter( const QString &layerId, const QgsExpression &expression );
%Docstring
Set a filter for the given layer.
:param layerId: the layer to filter
:param expression: the filter expression
.. versionadded:: 4.0
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -30,17 +30,7 @@ also available.
public:
virtual bool isFilterThreadSafe() const /Deprecated="Since 4.0. "/;
%Docstring
Returns ``True`` if the filterFeature function is thread safe, which
will lead to reliance on layer ID instead of the raw layer pointer.
.. versionadded:: 4.0
.. deprecated:: 4.0
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest ) const = 0;
%Docstring
Add additional filters to the feature request to further restrict the
features returned by the request. Derived classes must implement this
@ -48,22 +38,6 @@ method.
:param layer: the layer to filter
:param featureRequest: the feature request to update
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &featureRequest ) const;
%Docstring
Add additional filters to the feature request to further restrict the
features returned by the request. Derived classes must implement this
method.
:param layerId: the layer ID to filter
:param featureRequest: the feature request to update
.. versionadded:: 4.0
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const = 0;

View File

@ -1,81 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilterprovidergroup.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureFilterProviderGroup : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
%End
%TypeHeaderCode
#include "qgsfeaturefilterprovidergroup.h"
%End
public:
QgsFeatureFilterProviderGroup();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Filter the features of the layer.
:param layer: the layer to control
:param filterFeatures: the request to fill
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer.
:param layerId: the layer ID to control
:param filterFeatures: the request to fill
.. versionadded:: 4.0
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QgsFeatureFilterProviderGroup &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring
Add another filter provider to the group
:param provider: The provider to add
:return: itself
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilterprovidergroup.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -1,60 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgroupedfeaturefilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsGroupedFeatureFilterProvider : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgsgroupedfeaturefilterprovider.h"
%End
public:
QgsGroupedFeatureFilterProvider();
%Docstring
Constructor
%End
virtual bool isFilterThreadSafe() const /Deprecated/;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated/;
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsGroupedFeatureFilterProvider *clone() const /Factory/;
QgsGroupedFeatureFilterProvider &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring
Add another filter provider to the group
:param provider: The provider to add
:return: itself
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgroupedfeaturefilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -825,24 +825,12 @@ Deletes a style from the database
- msgError: a descriptive error message if any occurs
%End
enum class SaveStyleResult
{
Success,
QmlGenerationFailed,
SldGenerationFailed,
DatabaseWriteFailed,
};
typedef QFlags<QgsMapLayer::SaveStyleResult> SaveStyleResults;
virtual void saveStyleToDatabase( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) /Deprecated="Since 4.0. Use saveStyleToDatabaseV2() instead."/;
virtual void saveStyleToDatabase( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Saves QML and SLD representations of the layer's style to a table in the
database.
Saves named and sld style of the layer to the style table in the db.
:param name: Style name
:param description: A description of the style
@ -859,33 +847,9 @@ database.
Use :py:func:`QgsProviderRegistry.styleExists()` to test in advance if a style already exists and handle this appropriately
in your client code.
:return: - msgError: a descriptive error message if any occurs
.. deprecated:: 4.0
Use :py:func:`~QgsMapLayer.saveStyleToDatabaseV2` instead.
:return: a descriptive error message if any occurs
%End
QgsMapLayer::SaveStyleResults saveStyleToDatabaseV2( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Saves QML and SLD representations of the layer's style to a table in the
database.
:param name: Style name
:param description: A description of the style
:param useAsDefault: Set to ``True`` if style should be used as the
default style for the layer
:param uiFileContent:
:param categories: the style categories to be saved.
:return: - flags representing whether QML or SLD storing was successful
- msgError: a descriptive error message if any occurs
.. versionadded:: 4.0
%End
virtual QString loadNamedStyle( const QString &theURI, bool &resultFlag /Out/, bool loadFromLocalDb,

View File

@ -217,8 +217,6 @@ Creates an OGC expression XML element from the ``exp`` expression.
};
/************************************************************************
* This file has been generated automatically from *
* *

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,6 @@
%Include auto_generated/qgsexpressioncontextscopegenerator.sip
%Include auto_generated/qgsexpressionfieldbuffer.sip
%Include auto_generated/qgsfeature.sip
%Include auto_generated/qgsfeatureexpressionfilterprovider.sip
%Include auto_generated/qgsfeaturepickermodel.sip
%Include auto_generated/qgsfeaturepickermodelbase.sip
%Include auto_generated/qgsfeaturefiltermodel.sip
@ -78,7 +77,6 @@
%Include auto_generated/qgsgeometryvalidator.sip
%Include auto_generated/qgsgml.sip
%Include auto_generated/qgsgmlschema.sip
%Include auto_generated/qgsgroupedfeaturefilterprovider.sip
%Include auto_generated/qgsgrouplayer.sip
%Include auto_generated/qgshistogram.sip
%Include auto_generated/qgshstoreutils.sip

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsaccesscontrol.h
try:
QgsAccessControl.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsAccessControl.__overridden_methods__ = ['filterFeatures', 'clone', 'layerAttributes']
except (NameError, AttributeError):
pass

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsfeaturefilter.h
try:
QgsFeatureFilter.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsFeatureFilter.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsfeaturefilterprovidergroup.h
try:
QgsFeatureFilterProviderGroup.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsFeatureFilterProviderGroup.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -35,15 +35,6 @@ Constructor
~QgsAccessControl();
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsAccessControl *clone() const /Factory/;
void resolveFilterFeatures( const QList<QgsMapLayer *> &layers );
%Docstring
Resolve features' filter of layers The method fetch filter's expressions
@ -58,6 +49,23 @@ for efficiency; between each requests, the cache must be cleared using
void unresolveFilterFeatures();
%Docstring
Clear expression's cache computed from `resolveFilterFeatures`
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QString extraSubsetString( const QgsVectorLayer *layer ) const;
@ -103,6 +111,17 @@ Returns the layer delete right
:param layer: the layer to control
:return: ``True`` if we can do a delete
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
%Docstring
Returns the authorized layer attributes
:param layer: the layer to control
:param attributes: the list of attribute
:return: the list of visible attributes
%End
bool allowToEdit( const QgsVectorLayer *layer, const QgsFeature &feature ) const;

View File

@ -16,10 +16,6 @@ class QgsFeatureFilter : QgsFeatureFilterProvider
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
.. deprecated:: 3.4
Use :py:class:`QgsFeatureExpressionFilterProvider`
%End
%TypeHeaderCode
@ -31,14 +27,25 @@ per-layer basis.
Constructor
%End
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
void setFilter( const QgsVectorLayer *layer, const QgsExpression &expression );
%Docstring

View File

@ -14,10 +14,6 @@ class QgsFeatureFilterProviderGroup : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
.. deprecated:: 3.4
Use :py:class:`QgsGroupedFeatureFilterProvider`
%End
%TypeHeaderCode
@ -29,14 +25,25 @@ A filter filter provider grouping several filter providers.
Constructor
%End
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer.
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProviderGroup *clone() const /Factory/;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QgsFeatureFilterProviderGroup &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring

View File

@ -1,17 +1,16 @@
QgsAccessControl.allowToEdit: src/server/qgsaccesscontrol.h#L137
QgsAccessControl.clone: src/server/qgsaccesscontrol.h#L78
QgsAccessControl.extraSubsetString: src/server/qgsaccesscontrol.h#L101
QgsAccessControl.fillCacheKey: src/server/qgsaccesscontrol.h#L143
QgsAccessControl.filterFeatures: src/server/qgsaccesscontrol.h#L76
QgsAccessControl.isFilterThreadSafe: src/server/qgsaccesscontrol.h#L74
QgsAccessControl.layerAttributes: src/server/qgsaccesscontrol.h#L77
QgsAccessControl.layerDeletePermission: src/server/qgsaccesscontrol.h#L129
QgsAccessControl.layerInsertPermission: src/server/qgsaccesscontrol.h#L115
QgsAccessControl.layerReadPermission: src/server/qgsaccesscontrol.h#L108
QgsAccessControl.layerUpdatePermission: src/server/qgsaccesscontrol.h#L122
QgsAccessControl.registerAccessControl: src/server/qgsaccesscontrol.h#L150
QgsAccessControl.resolveFilterFeatures: src/server/qgsaccesscontrol.h#L89
QgsAccessControl.unresolveFilterFeatures: src/server/qgsaccesscontrol.h#L94
QgsAccessControl.allowToEdit: src/server/qgsaccesscontrol.h#L152
QgsAccessControl.clone: src/server/qgsaccesscontrol.h#L101
QgsAccessControl.extraSubsetString: src/server/qgsaccesscontrol.h#L108
QgsAccessControl.fillCacheKey: src/server/qgsaccesscontrol.h#L158
QgsAccessControl.filterFeatures: src/server/qgsaccesscontrol.h#L95
QgsAccessControl.layerAttributes: src/server/qgsaccesscontrol.h#L144
QgsAccessControl.layerDeletePermission: src/server/qgsaccesscontrol.h#L136
QgsAccessControl.layerInsertPermission: src/server/qgsaccesscontrol.h#L122
QgsAccessControl.layerReadPermission: src/server/qgsaccesscontrol.h#L115
QgsAccessControl.layerUpdatePermission: src/server/qgsaccesscontrol.h#L129
QgsAccessControl.registerAccessControl: src/server/qgsaccesscontrol.h#L165
QgsAccessControl.resolveFilterFeatures: src/server/qgsaccesscontrol.h#L83
QgsAccessControl.unresolveFilterFeatures: src/server/qgsaccesscontrol.h#L88
QgsAccessControl: src/server/qgsaccesscontrol.h#L35
QgsAccessControlFilter.allowToEdit: src/server/qgsaccesscontrolfilter.h#L109
QgsAccessControlFilter.authorizedLayerAttributes: src/server/qgsaccesscontrolfilter.h#L101
@ -55,17 +54,15 @@ QgsFcgiServerRequest.data: src/server/qgsfcgiserverrequest.h#L36
QgsFcgiServerRequest.hasError: src/server/qgsfcgiserverrequest.h#L41
QgsFcgiServerRequest.header: src/server/qgsfcgiserverrequest.h#L49
QgsFcgiServerRequest: src/server/qgsfcgiserverrequest.h#L31
QgsFeatureFilter.clone: src/server/qgsfeaturefilter.h#L44
QgsFeatureFilter.filterFeatures: src/server/qgsfeaturefilter.h#L42
QgsFeatureFilter.isFilterThreadSafe: src/server/qgsfeaturefilter.h#L40
QgsFeatureFilter.layerAttributes: src/server/qgsfeaturefilter.h#L43
QgsFeatureFilter.setFilter: src/server/qgsfeaturefilter.h#L51
QgsFeatureFilter: src/server/qgsfeaturefilter.h#L34
QgsFeatureFilterProviderGroup.clone: src/server/qgsfeaturefilterprovidergroup.h#L42
QgsFeatureFilterProviderGroup.filterFeatures: src/server/qgsfeaturefilterprovidergroup.h#L40
QgsFeatureFilterProviderGroup.isFilterThreadSafe: src/server/qgsfeaturefilterprovidergroup.h#L38
QgsFeatureFilterProviderGroup.layerAttributes: src/server/qgsfeaturefilterprovidergroup.h#L41
QgsFeatureFilterProviderGroup: src/server/qgsfeaturefilterprovidergroup.h#L32
QgsFeatureFilter.clone: src/server/qgsfeaturefilter.h#L52
QgsFeatureFilter.filterFeatures: src/server/qgsfeaturefilter.h#L44
QgsFeatureFilter.layerAttributes: src/server/qgsfeaturefilter.h#L46
QgsFeatureFilter.setFilter: src/server/qgsfeaturefilter.h#L59
QgsFeatureFilter: src/server/qgsfeaturefilter.h#L33
QgsFeatureFilterProviderGroup.clone: src/server/qgsfeaturefilterprovidergroup.h#L50
QgsFeatureFilterProviderGroup.filterFeatures: src/server/qgsfeaturefilterprovidergroup.h#L42
QgsFeatureFilterProviderGroup.layerAttributes: src/server/qgsfeaturefilterprovidergroup.h#L44
QgsFeatureFilterProviderGroup: src/server/qgsfeaturefilterprovidergroup.h#L31
QgsOgcServiceException.code: src/server/qgsserverexception.h#L94
QgsOgcServiceException.formatResponse: src/server/qgsserverexception.h#L102
QgsOgcServiceException.locator: src/server/qgsserverexception.h#L97

View File

@ -10055,9 +10055,6 @@ QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks = Qgis.LayoutRenderFlag.AlwaysUs
QgsLayoutRenderContext.Flag.FlagAlwaysUseGlobalMasks = Qgis.LayoutRenderFlag.AlwaysUseGlobalMasks
QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks.is_monkey_patched = True
QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks.__doc__ = "When applying clipping paths for selective masking, always use global (\"entire map\") paths, instead of calculating local clipping paths per rendered feature. This results in considerably more complex layout exports in all current Qt versions. This flag only applies to vector layout exports. \n.. versionadded:: 3.38"
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature = Qgis.LayoutRenderFlag.LimitCoverageLayerRenderToCurrentFeature
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature.is_monkey_patched = True
QgsLayoutRenderContext.LimitCoverageLayerRenderToCurrentFeature.__doc__ = "Limit coverage layer rendering to the current atlas feature. \n.. versionadded:: 4.0"
Qgis.LayoutRenderFlag.__doc__ = """Flags for controlling how a layout is rendered.
.. note::
@ -10123,10 +10120,6 @@ Qgis.LayoutRenderFlag.__doc__ = """Flags for controlling how a layout is rendere
Available as ``QgsLayoutRenderContext.FlagAlwaysUseGlobalMasks`` in older QGIS releases.
* ``LimitCoverageLayerRenderToCurrentFeature``: Limit coverage layer rendering to the current atlas feature.
.. versionadded:: 4.0
"""
# --
@ -11411,10 +11404,6 @@ Qgis.MouseHandlesAction.ResizeLeftUp.__doc__ = "Resize left up (Top left handle)
Qgis.MouseHandlesAction.ResizeRightUp.__doc__ = "Resize right up (Top right handle)"
Qgis.MouseHandlesAction.ResizeLeftDown.__doc__ = "Resize left down (Bottom left handle)"
Qgis.MouseHandlesAction.ResizeRightDown.__doc__ = "Resize right down (Bottom right handle)"
Qgis.MouseHandlesAction.RotateTopLeft.__doc__ = "Rotate from top left handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateTopRight.__doc__ = "Rotate from top right handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateBottomLeft.__doc__ = "Rotate from bottom left handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.RotateBottomRight.__doc__ = "Rotate right bottom right handle. \n.. versionadded:: 4.0"
Qgis.MouseHandlesAction.SelectItem.__doc__ = "Select item"
Qgis.MouseHandlesAction.NoAction.__doc__ = "No action"
Qgis.MouseHandlesAction.__doc__ = """Action to be performed by the mouse handles
@ -11430,22 +11419,6 @@ Qgis.MouseHandlesAction.__doc__ = """Action to be performed by the mouse handles
* ``ResizeRightUp``: Resize right up (Top right handle)
* ``ResizeLeftDown``: Resize left down (Bottom left handle)
* ``ResizeRightDown``: Resize right down (Bottom right handle)
* ``RotateTopLeft``: Rotate from top left handle.
.. versionadded:: 4.0
* ``RotateTopRight``: Rotate from top right handle.
.. versionadded:: 4.0
* ``RotateBottomLeft``: Rotate from bottom left handle.
.. versionadded:: 4.0
* ``RotateBottomRight``: Rotate right bottom right handle.
.. versionadded:: 4.0
* ``SelectItem``: Select item
* ``NoAction``: No action

View File

@ -1,5 +0,0 @@
# The following has been generated automatically from src/core/qgsfeatureexpressionfilterprovider.h
try:
QgsFeatureExpressionFilterProvider.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,6 +1,5 @@
# The following has been generated automatically from src/core/qgsfeaturefilterprovider.h
try:
QgsFeatureFilterProvider.__virtual_methods__ = ['isFilterThreadSafe', 'filterFeatures']
QgsFeatureFilterProvider.__abstract_methods__ = ['layerAttributes', 'clone']
QgsFeatureFilterProvider.__abstract_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,5 +0,0 @@
# The following has been generated automatically from src/core/qgsgroupedfeaturefilterprovider.h
try:
QgsGroupedFeatureFilterProvider.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

File diff suppressed because one or more lines are too long

View File

@ -16,9 +16,7 @@
typedef QVector<QgsPointXY> QgsPolylineXY;
typedef QVector<QgsPoint> QgsPolyline;
typedef QVector<QVector< QgsPoint >> QgsMultiPolyline;
typedef QgsPointSequence QgsPolyline;
typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;

View File

@ -73,26 +73,6 @@ Sets whether the coverage layer should be hidden in map items in the
layouts.
.. seealso:: :py:func:`hideCoverage`
%End
bool limitCoverageLayerRenderToCurrentFeature() const;
%Docstring
Returns ``True`` if the atlas is set to limit rendering on the coverage
layer to the current feature.
.. seealso:: :py:func:`setHideCoverage`
.. versionadded:: 4.0
%End
void setLimitCoverageLayerRenderToCurrentFeature( bool limit );
%Docstring
Sets whether the rendering of the coverage layer should be limited to
the current feature.
.. seealso:: :py:func:`hideCoverage`
.. versionadded:: 4.0
%End
QString filenameExpression() const;

View File

@ -2912,7 +2912,6 @@ The development version
LosslessImageRendering,
SynchronousLegendGraphics,
AlwaysUseGlobalMasks,
LimitCoverageLayerRenderToCurrentFeature,
};
typedef QFlags<Qgis::LayoutRenderFlag> LayoutRenderFlags;
@ -3347,10 +3346,6 @@ The development version
ResizeRightUp,
ResizeLeftDown,
ResizeRightDown,
RotateTopLeft,
RotateTopRight,
RotateBottomLeft,
RotateBottomRight,
SelectItem,
NoAction
};

View File

@ -1,57 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeatureexpressionfilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureExpressionFilterProvider : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgsfeatureexpressionfilterprovider.h"
%End
public:
QgsFeatureExpressionFilterProvider();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated/;
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureExpressionFilterProvider *clone() const /Factory/;
void setFilter( const QString &layerId, const QgsExpression &expression );
%Docstring
Set a filter for the given layer.
:param layerId: the layer to filter
:param expression: the filter expression
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeatureexpressionfilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -1,93 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureFilter : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
%End
%TypeHeaderCode
#include "qgsfeaturefilter.h"
%End
public:
QgsFeatureFilter();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layerId: the layer ID to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
void setFilter( const QgsVectorLayer *layer, const QgsExpression &expression ) /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Set a filter for the given layer.
:param layer: the layer to filter
:param expression: the filter expression
.. deprecated:: 4.0
Use the layer ID variant.
%End
void setFilter( const QString &layerId, const QgsExpression &expression );
%Docstring
Set a filter for the given layer.
:param layerId: the layer to filter
:param expression: the filter expression
.. versionadded:: 4.0
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -30,17 +30,7 @@ also available.
public:
virtual bool isFilterThreadSafe() const /Deprecated="Since 4.0. "/;
%Docstring
Returns ``True`` if the filterFeature function is thread safe, which
will lead to reliance on layer ID instead of the raw layer pointer.
.. versionadded:: 4.0
.. deprecated:: 4.0
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest ) const = 0;
%Docstring
Add additional filters to the feature request to further restrict the
features returned by the request. Derived classes must implement this
@ -48,22 +38,6 @@ method.
:param layer: the layer to filter
:param featureRequest: the feature request to update
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &featureRequest ) const;
%Docstring
Add additional filters to the feature request to further restrict the
features returned by the request. Derived classes must implement this
method.
:param layerId: the layer ID to filter
:param featureRequest: the feature request to update
.. versionadded:: 4.0
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const = 0;

View File

@ -1,81 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilterprovidergroup.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsFeatureFilterProviderGroup : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
%End
%TypeHeaderCode
#include "qgsfeaturefilterprovidergroup.h"
%End
public:
QgsFeatureFilterProviderGroup();
%Docstring
Constructor
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated="Since 4.0. Use the layer ID variant."/;
%Docstring
Filter the features of the layer.
:param layer: the layer to control
:param filterFeatures: the request to fill
.. deprecated:: 4.0
Use the layer ID variant.
%End
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer.
:param layerId: the layer ID to control
:param filterFeatures: the request to fill
.. versionadded:: 4.0
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QgsFeatureFilterProviderGroup &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring
Add another filter provider to the group
:param provider: The provider to add
:return: itself
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturefilterprovidergroup.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -1,60 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgroupedfeaturefilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsGroupedFeatureFilterProvider : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgsgroupedfeaturefilterprovider.h"
%End
public:
QgsGroupedFeatureFilterProvider();
%Docstring
Constructor
%End
virtual bool isFilterThreadSafe() const /Deprecated/;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const /Deprecated/;
virtual void filterFeatures( const QString &layerId, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsGroupedFeatureFilterProvider *clone() const /Factory/;
QgsGroupedFeatureFilterProvider &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring
Add another filter provider to the group
:param provider: The provider to add
:return: itself
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgroupedfeaturefilterprovider.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -825,24 +825,12 @@ Deletes a style from the database
- msgError: a descriptive error message if any occurs
%End
enum class SaveStyleResult
{
Success,
QmlGenerationFailed,
SldGenerationFailed,
DatabaseWriteFailed,
};
typedef QFlags<QgsMapLayer::SaveStyleResult> SaveStyleResults;
virtual void saveStyleToDatabase( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) /Deprecated="Since 4.0. Use saveStyleToDatabaseV2() instead."/;
virtual void saveStyleToDatabase( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Saves QML and SLD representations of the layer's style to a table in the
database.
Saves named and sld style of the layer to the style table in the db.
:param name: Style name
:param description: A description of the style
@ -859,33 +847,9 @@ database.
Use :py:func:`QgsProviderRegistry.styleExists()` to test in advance if a style already exists and handle this appropriately
in your client code.
:return: - msgError: a descriptive error message if any occurs
.. deprecated:: 4.0
Use :py:func:`~QgsMapLayer.saveStyleToDatabaseV2` instead.
:return: a descriptive error message if any occurs
%End
QgsMapLayer::SaveStyleResults saveStyleToDatabaseV2( const QString &name, const QString &description,
bool useAsDefault, const QString &uiFileContent,
QString &msgError /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Saves QML and SLD representations of the layer's style to a table in the
database.
:param name: Style name
:param description: A description of the style
:param useAsDefault: Set to ``True`` if style should be used as the
default style for the layer
:param uiFileContent:
:param categories: the style categories to be saved.
:return: - flags representing whether QML or SLD storing was successful
- msgError: a descriptive error message if any occurs
.. versionadded:: 4.0
%End
virtual QString loadNamedStyle( const QString &theURI, bool &resultFlag /Out/, bool loadFromLocalDb,

View File

@ -217,8 +217,6 @@ Creates an OGC expression XML element from the ``exp`` expression.
};
/************************************************************************
* This file has been generated automatically from *
* *

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,6 @@
%Include auto_generated/qgsexpressioncontextscopegenerator.sip
%Include auto_generated/qgsexpressionfieldbuffer.sip
%Include auto_generated/qgsfeature.sip
%Include auto_generated/qgsfeatureexpressionfilterprovider.sip
%Include auto_generated/qgsfeaturepickermodel.sip
%Include auto_generated/qgsfeaturepickermodelbase.sip
%Include auto_generated/qgsfeaturefiltermodel.sip
@ -78,7 +77,6 @@
%Include auto_generated/qgsgeometryvalidator.sip
%Include auto_generated/qgsgml.sip
%Include auto_generated/qgsgmlschema.sip
%Include auto_generated/qgsgroupedfeaturefilterprovider.sip
%Include auto_generated/qgsgrouplayer.sip
%Include auto_generated/qgshistogram.sip
%Include auto_generated/qgshstoreutils.sip

View File

@ -114,13 +114,14 @@ class GdalUtils:
except OSError: # https://travis-ci.org/m-kuhn/QGIS#L1493-L1526
pass
if isDarwin and os.path.isfile(
os.path.join(QgsApplication.prefixPath(), "Contents", "MacOS", "gdalinfo")
os.path.join(QgsApplication.prefixPath(), "bin", "gdalinfo")
):
# Looks like there's a bundled gdal. Let's use it.
os.environ["PATH"] = "{}{}{}".format(
os.path.join(QgsApplication.prefixPath(), "Contents", "MacOS"),
os.pathsep,
envval,
os.path.join(QgsApplication.prefixPath(), "bin"), os.pathsep, envval
)
os.environ["DYLD_LIBRARY_PATH"] = os.path.join(
QgsApplication.prefixPath(), "lib"
)
else:
# Other platforms should use default gdal finder codepath

View File

@ -57,13 +57,9 @@ class BatchAlgorithmDialog(QgsProcessingBatchAlgorithmDialogBase):
def runAsSingle(self):
self.close()
alg_instance = self.algorithm().create()
dlg = alg_instance.createCustomParametersWidget(parent=iface.mainWindow())
if not dlg:
from processing.gui.AlgorithmDialog import AlgorithmDialog
dlg = AlgorithmDialog(alg_instance, parent=iface.mainWindow())
from processing.gui.AlgorithmDialog import AlgorithmDialog
dlg = AlgorithmDialog(self.algorithm().create(), parent=iface.mainWindow())
dlg.show()
dlg.exec()

View File

@ -79,21 +79,13 @@ class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
"""
return "examplescripts"
def shortDescription(self) -> str:
"""
Returns an optional translated short description of the algorithm, displayed
on hover in Processing Toolbox. This should be at most a single sentence, e.g.,
Converts 2D features to 3D by sampling a DEM raster.
"""
return "Example algorithm short description on hover"
def shortHelpString(self) -> str:
"""
Returns a localised helper string for the algorithm displayed in the dialog.
This string should provide a basic description about what the algorithm does and the
Returns a localised short helper string for the algorithm. This string
should provide a basic description about what the algorithm does and the
parameters and outputs associated with it.
"""
return "Example algorithm description"
return "Example algorithm short description"
def initAlgorithm(self, config: Optional[dict[str, Any]] = None):
"""
@ -103,16 +95,13 @@ class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
# We add the input vector features source. It can have any kind of
# geometry.
input_layer = QgsProcessingParameterFeatureSource(
self.INPUT,
"Input layer",
[QgsProcessing.SourceType.TypeVectorAnyGeometry],
self.addParameter(
QgsProcessingParameterFeatureSource(
self.INPUT,
"Input layer",
[QgsProcessing.SourceType.TypeVectorAnyGeometry],
)
)
input_layer.setHelp(
"A descriptive, translated string explaining the parameters behavior and use in depth."
)
self.addParameter(input_layer)
# We add a feature sink in which to store our processed features (this
# usually takes the form of a newly created vector layer when the

View File

@ -1,6 +1,6 @@
# See ../CMakeLists.txt for info on staged-plugins* and clean-staged-plugins targets
set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis)
set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis)
set(PY_FILES
__init__.py

View File

@ -658,14 +658,8 @@ class Repositories(QObject):
.text()
.strip()
)
supports_qt6 = pluginNodes.item(i).firstChildElement(
"supports_qt6"
).text().strip().upper() in ["TRUE", "YES"]
if not qgisMaximumVersion:
if qgisMinimumVersion[0] == "3" and supports_qt6:
qgisMaximumVersion = "4.99"
else:
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
# if compatible, add the plugin to the list
if not pluginNodes.item(i).firstChildElement(
"disabled"
@ -851,10 +845,7 @@ class Plugins(QObject):
qgisMinimumVersion = "0"
qgisMaximumVersion = pluginMetadata("qgisMaximumVersion").strip()
if not qgisMaximumVersion:
if qgisMinimumVersion[0] == "3" and supports_qt6:
qgisMaximumVersion = "4.99"
else:
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
# if compatible, add the plugin to the list
if not isCompatible(
pyQgisVersion(), qgisMinimumVersion, qgisMaximumVersion

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsaccesscontrol.h
try:
QgsAccessControl.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsAccessControl.__overridden_methods__ = ['filterFeatures', 'clone', 'layerAttributes']
except (NameError, AttributeError):
pass

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsfeaturefilter.h
try:
QgsFeatureFilter.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsFeatureFilter.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -1,5 +1,5 @@
# The following has been generated automatically from src/server/qgsfeaturefilterprovidergroup.h
try:
QgsFeatureFilterProviderGroup.__overridden_methods__ = ['isFilterThreadSafe', 'filterFeatures', 'layerAttributes', 'clone']
QgsFeatureFilterProviderGroup.__overridden_methods__ = ['filterFeatures', 'layerAttributes', 'clone']
except (NameError, AttributeError):
pass

View File

@ -35,15 +35,6 @@ Constructor
~QgsAccessControl();
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsAccessControl *clone() const /Factory/;
void resolveFilterFeatures( const QList<QgsMapLayer *> &layers );
%Docstring
Resolve features' filter of layers The method fetch filter's expressions
@ -58,6 +49,23 @@ for efficiency; between each requests, the cache must be cleared using
void unresolveFilterFeatures();
%Docstring
Clear expression's cache computed from `resolveFilterFeatures`
%End
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QString extraSubsetString( const QgsVectorLayer *layer ) const;
@ -103,6 +111,17 @@ Returns the layer delete right
:param layer: the layer to control
:return: ``True`` if we can do a delete
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
%Docstring
Returns the authorized layer attributes
:param layer: the layer to control
:param attributes: the list of attribute
:return: the list of visible attributes
%End
bool allowToEdit( const QgsVectorLayer *layer, const QgsFeature &feature ) const;

View File

@ -16,10 +16,6 @@ class QgsFeatureFilter : QgsFeatureFilterProvider
%Docstring(signature="appended")
A feature filter provider allowing to set filter expressions on a
per-layer basis.
.. deprecated:: 3.4
Use :py:class:`QgsFeatureExpressionFilterProvider`
%End
%TypeHeaderCode
@ -31,14 +27,25 @@ per-layer basis.
Constructor
%End
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
void setFilter( const QgsVectorLayer *layer, const QgsExpression &expression );
%Docstring

View File

@ -14,10 +14,6 @@ class QgsFeatureFilterProviderGroup : QgsFeatureFilterProvider
{
%Docstring(signature="appended")
A filter filter provider grouping several filter providers.
.. deprecated:: 3.4
Use :py:class:`QgsGroupedFeatureFilterProvider`
%End
%TypeHeaderCode
@ -29,14 +25,25 @@ A filter filter provider grouping several filter providers.
Constructor
%End
virtual bool isFilterThreadSafe() const;
virtual void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const;
%Docstring
Filter the features of the layer.
:param layer: the layer to control
:param filterFeatures: the request to fill
%End
virtual QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const;
virtual QgsFeatureFilterProviderGroup *clone() const /Factory/;
virtual QgsFeatureFilterProvider *clone() const /Factory/;
%Docstring
Returns a clone of the object
:return: A clone
%End
QgsFeatureFilterProviderGroup &addProvider( const QgsFeatureFilterProvider *provider );
%Docstring

View File

@ -1,17 +1,16 @@
QgsAccessControl.allowToEdit: src/server/qgsaccesscontrol.h#L137
QgsAccessControl.clone: src/server/qgsaccesscontrol.h#L78
QgsAccessControl.extraSubsetString: src/server/qgsaccesscontrol.h#L101
QgsAccessControl.fillCacheKey: src/server/qgsaccesscontrol.h#L143
QgsAccessControl.filterFeatures: src/server/qgsaccesscontrol.h#L76
QgsAccessControl.isFilterThreadSafe: src/server/qgsaccesscontrol.h#L74
QgsAccessControl.layerAttributes: src/server/qgsaccesscontrol.h#L77
QgsAccessControl.layerDeletePermission: src/server/qgsaccesscontrol.h#L129
QgsAccessControl.layerInsertPermission: src/server/qgsaccesscontrol.h#L115
QgsAccessControl.layerReadPermission: src/server/qgsaccesscontrol.h#L108
QgsAccessControl.layerUpdatePermission: src/server/qgsaccesscontrol.h#L122
QgsAccessControl.registerAccessControl: src/server/qgsaccesscontrol.h#L150
QgsAccessControl.resolveFilterFeatures: src/server/qgsaccesscontrol.h#L89
QgsAccessControl.unresolveFilterFeatures: src/server/qgsaccesscontrol.h#L94
QgsAccessControl.allowToEdit: src/server/qgsaccesscontrol.h#L152
QgsAccessControl.clone: src/server/qgsaccesscontrol.h#L101
QgsAccessControl.extraSubsetString: src/server/qgsaccesscontrol.h#L108
QgsAccessControl.fillCacheKey: src/server/qgsaccesscontrol.h#L158
QgsAccessControl.filterFeatures: src/server/qgsaccesscontrol.h#L95
QgsAccessControl.layerAttributes: src/server/qgsaccesscontrol.h#L144
QgsAccessControl.layerDeletePermission: src/server/qgsaccesscontrol.h#L136
QgsAccessControl.layerInsertPermission: src/server/qgsaccesscontrol.h#L122
QgsAccessControl.layerReadPermission: src/server/qgsaccesscontrol.h#L115
QgsAccessControl.layerUpdatePermission: src/server/qgsaccesscontrol.h#L129
QgsAccessControl.registerAccessControl: src/server/qgsaccesscontrol.h#L165
QgsAccessControl.resolveFilterFeatures: src/server/qgsaccesscontrol.h#L83
QgsAccessControl.unresolveFilterFeatures: src/server/qgsaccesscontrol.h#L88
QgsAccessControl: src/server/qgsaccesscontrol.h#L35
QgsAccessControlFilter.allowToEdit: src/server/qgsaccesscontrolfilter.h#L109
QgsAccessControlFilter.authorizedLayerAttributes: src/server/qgsaccesscontrolfilter.h#L101
@ -55,17 +54,15 @@ QgsFcgiServerRequest.data: src/server/qgsfcgiserverrequest.h#L36
QgsFcgiServerRequest.hasError: src/server/qgsfcgiserverrequest.h#L41
QgsFcgiServerRequest.header: src/server/qgsfcgiserverrequest.h#L49
QgsFcgiServerRequest: src/server/qgsfcgiserverrequest.h#L31
QgsFeatureFilter.clone: src/server/qgsfeaturefilter.h#L44
QgsFeatureFilter.filterFeatures: src/server/qgsfeaturefilter.h#L42
QgsFeatureFilter.isFilterThreadSafe: src/server/qgsfeaturefilter.h#L40
QgsFeatureFilter.layerAttributes: src/server/qgsfeaturefilter.h#L43
QgsFeatureFilter.setFilter: src/server/qgsfeaturefilter.h#L51
QgsFeatureFilter: src/server/qgsfeaturefilter.h#L34
QgsFeatureFilterProviderGroup.clone: src/server/qgsfeaturefilterprovidergroup.h#L42
QgsFeatureFilterProviderGroup.filterFeatures: src/server/qgsfeaturefilterprovidergroup.h#L40
QgsFeatureFilterProviderGroup.isFilterThreadSafe: src/server/qgsfeaturefilterprovidergroup.h#L38
QgsFeatureFilterProviderGroup.layerAttributes: src/server/qgsfeaturefilterprovidergroup.h#L41
QgsFeatureFilterProviderGroup: src/server/qgsfeaturefilterprovidergroup.h#L32
QgsFeatureFilter.clone: src/server/qgsfeaturefilter.h#L52
QgsFeatureFilter.filterFeatures: src/server/qgsfeaturefilter.h#L44
QgsFeatureFilter.layerAttributes: src/server/qgsfeaturefilter.h#L46
QgsFeatureFilter.setFilter: src/server/qgsfeaturefilter.h#L59
QgsFeatureFilter: src/server/qgsfeaturefilter.h#L33
QgsFeatureFilterProviderGroup.clone: src/server/qgsfeaturefilterprovidergroup.h#L50
QgsFeatureFilterProviderGroup.filterFeatures: src/server/qgsfeaturefilterprovidergroup.h#L42
QgsFeatureFilterProviderGroup.layerAttributes: src/server/qgsfeaturefilterprovidergroup.h#L44
QgsFeatureFilterProviderGroup: src/server/qgsfeaturefilterprovidergroup.h#L31
QgsOgcServiceException.code: src/server/qgsserverexception.h#L94
QgsOgcServiceException.formatResponse: src/server/qgsserverexception.h#L102
QgsOgcServiceException.locator: src/server/qgsserverexception.h#L97

View File

@ -1,6 +1,6 @@
# See ../CMakeLists.txt for info on staged-plugins* and clean-staged-plugins targets
set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis)
set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis)
set(PY_FILES
__init__.py

View File

@ -58,7 +58,6 @@ resources/cpt-city-qgis-min/selections/reds.xml
resources/cpt-city-qgis-min/wkp/schwarzwald/COPYING.xml
resources/data/world_map_generalize.model3
scripts/spell_check/spelling.dat
platform/macos/pymacdeployqt.py
scripts/spell_check/test.sh
src/server/qgis_wms.xmi
src/plugins/grass/modules/v.generalize.qgm

View File

@ -327,6 +327,30 @@ GENERATE_EXPORT_HEADER(
set(QGIS_3D_HDRS ${QGIS_3D_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/qgis_3d.h)
if(NOT APPLE OR NOT QGIS_MACAPP_FRAMEWORK)
install(FILES ${QGIS_3D_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
else()
set_target_properties(qgis_3d PROPERTIES
# no moc headers, messes up PROPERTIES syntax
CLEAN_DIRECT_OUTPUT 1
FRAMEWORK 1
FRAMEWORK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}"
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/mac/framework.info.plist.in"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${COMPLETE_VERSION}
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis3_3d
BUILD_WITH_INSTALL_RPATH TRUE
PUBLIC_HEADER "${QGIS_3D_HDRS}"
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
)
# generated export header does not get copied with PUBLIC_HEADER files
add_custom_command(TARGET qgis_3d
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy qgis_3d.h
"${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIB_SUBDIR}/qgis_3d.framework/Headers"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS qgis_3d.h
)
endif()
#generate unversioned libs for android
if (NOT ANDROID)
@ -347,11 +371,18 @@ if(CLANG_TIDY_EXE)
endif()
# install
if(NOT QGIS_MAC_BUNDLE)
install(FILES ${QGIS_3D_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
endif()
install(TARGETS qgis_3d
RUNTIME DESTINATION ${QGIS_BIN_DIR}
LIBRARY DESTINATION ${QGIS_LIB_DIR}
ARCHIVE DESTINATION ${QGIS_LIB_DIR})
ARCHIVE DESTINATION ${QGIS_LIB_DIR}
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR}
PUBLIC_HEADER DESTINATION ${QGIS_INCLUDE_DIR})
# Mac dev frameworks
if (APPLE AND QGIS_MACAPP_INSTALL_DEV)
install(TARGETS qgis_3d FRAMEWORK DESTINATION ${QGIS_MACAPP_DEV_PREFIX})
install(CODE "execute_process(COMMAND install_name_tool -id \"${QGIS_MACAPP_DEV_PREFIX}/qgis_3d.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_3d\" \"$ENV{DESTDIR}${QGIS_MACAPP_DEV_PREFIX}/qgis_3d.framework/qgis_3d\")")
install(CODE "execute_process(COMMAND install_name_tool -change \"${CMAKE_INSTALL_NAME_DIR}/qgis_core.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_core\" \"${QGIS_MACAPP_DEV_PREFIX}/qgis_core.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_core\" \"$ENV{DESTDIR}${QGIS_MACAPP_DEV_PREFIX}/qgis_3d.framework/qgis_3d\")")
endif()

View File

@ -64,7 +64,7 @@ void QgsDirectionalLightSettings::readXml( const QDomElement &elem, const QgsRea
mIntensity = elem.attribute( QStringLiteral( "intensity" ) ).toFloat();
}
bool QgsDirectionalLightSettings::operator==( const QgsDirectionalLightSettings &other ) const
bool QgsDirectionalLightSettings::operator==( const QgsDirectionalLightSettings &other )
{
return mDirection == other.mDirection && mColor == other.mColor && mIntensity == other.mIntensity;
}

Some files were not shown because too many files have changed in this diff Show More