diff -ruN qgis-2.18.12-orig/CMakeLists.txt qgis-2.18.12/CMakeLists.txt
--- qgis-2.18.12-orig/CMakeLists.txt	2017-08-28 16:26:42.000000000 +0900
+++ qgis-2.18.12/CMakeLists.txt	2017-08-28 16:30:02.000000000 +0900
@@ -586,9 +586,9 @@
     # 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 (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")
 
   ELSE (APPLE)
     # UNIX
diff -ruN qgis-2.18.12-orig/cmake/FindGRASS.cmake qgis-2.18.12/cmake/FindGRASS.cmake
--- qgis-2.18.12-orig/cmake/FindGRASS.cmake	2017-08-28 16:26:42.000000000 +0900
+++ qgis-2.18.12/cmake/FindGRASS.cmake	2017-08-28 16:30:02.000000000 +0900
@@ -48,7 +48,7 @@
           # FIND_* is invoked first with specified paths and NO_DEFAULT_PATH
           # and then again with no specified paths to search the default
           # locations. When an earlier FIND_* succeeds, subsequent FIND_*s
-          # searching for the same item do nothing. 
+          # searching for the same item do nothing.
           FIND_LIBRARY(LIB_PATH NAMES grass_${LIB} PATHS ${G_PREFIX}/lib NO_DEFAULT_PATH)
           FIND_LIBRARY(LIB_PATH NAMES grass_${LIB} PATHS ${G_PREFIX}/lib)
 
@@ -62,18 +62,18 @@
 
         # LIB_PATH is only temporary variable, so hide it (is it possible to delete a variable?)
         UNSET(LIB_PATH CACHE)
-    
+
         # Find off_t size
         IF( (GRASS_MAJOR_VERSION${GRASS_FIND_VERSION} EQUAL 7) AND (GRASS_MINOR_VERSION${GRASS_FIND_VERSION} GREATER 0) )
           SET(GRASS_TEST_MAPSET ${CMAKE_BINARY_DIR}/grass-location/PERMANENT)
-          FILE(MAKE_DIRECTORY ${GRASS_TEST_MAPSET}) 
-          FILE(WRITE ${GRASS_TEST_MAPSET}/DEFAULT_WIND "") 
+          FILE(MAKE_DIRECTORY ${GRASS_TEST_MAPSET})
+          FILE(WRITE ${GRASS_TEST_MAPSET}/DEFAULT_WIND "")
           FILE(WRITE ${GRASS_TEST_MAPSET}/WIND "")
           # grass command is not in G_PREFIX but in some bin dir, so it must be in PATH
           SET(GRASS_EXE grass7${GRASS_MINOR_VERSION${GRASS_FIND_VERSION}})
           #MESSAGE(STATUS "GRASS_EXE = ${GRASS_EXE}")
           EXECUTE_PROCESS(COMMAND ${GRASS_EXE} ${GRASS_TEST_MAPSET} --exec g.version -g
-            COMMAND grep build_off_t_size 
+            COMMAND grep build_off_t_size
             COMMAND sed "s/.*\\([0-9]\\).*/\\1/"
             ERROR_VARIABLE GRASS_TMP_ERROR
             OUTPUT_VARIABLE GRASS_OFF_T_SIZE${GRASS_FIND_VERSION}
@@ -98,9 +98,9 @@
                   SET( GRASS_OFF_T_SIZE${GRASS_FIND_VERSION} 4 )
                 ELSEIF( "${FILE_OFFSET_BITS}" STREQUAL "64" )
                   SET( GRASS_OFF_T_SIZE${GRASS_FIND_VERSION} 8 )
-                ENDIF()        
-              ENDIF()        
-            ENDIF()        
+                ENDIF()
+              ENDIF()
+            ENDIF()
           ENDIF()
         ENDIF()
 
@@ -142,19 +142,7 @@
 ENDIF (UNIX)
 
 IF (APPLE)
-  IF (GRASS_FIND_VERSION EQUAL 6)
-    LIST(APPEND GRASS_PATHS
-      /Applications/GRASS-6.3.app/Contents/MacOS
-      /Applications/GRASS-6.4.app/Contents/MacOS
-    )
-  ELSEIF (GRASS_FIND_VERSION EQUAL 7)
-    LIST(APPEND GRASS_PATHS
-      /Applications/GRASS-7.0.app/Contents/MacOS
-      /Applications/GRASS-7.1.app/Contents/MacOS
-      /Applications/GRASS-7.2.app/Contents/MacOS
-    )
-  ENDIF ()
-  LIST(APPEND GRASS_PATHS /Applications/GRASS.app/Contents/Resources)
+
 ENDIF (APPLE)
 
 IF (WITH_GRASS${GRASS_CACHE_VERSION})
diff -ruN qgis-2.18.12-orig/cmake/FindOSGEARTH.cmake qgis-2.18.12/cmake/FindOSGEARTH.cmake
--- qgis-2.18.12-orig/cmake/FindOSGEARTH.cmake	2017-08-28 16:26:42.000000000 +0900
+++ qgis-2.18.12/cmake/FindOSGEARTH.cmake	2017-08-28 16:30:02.000000000 +0900
@@ -10,7 +10,7 @@
 # directory, and source directory, respectively
 # OSGEARTHDIR or OSGEARTH_SOURCE_DIR: osg source directory, typically OpenSceneGraph
 # OSGEARTH_DIR or OSGEARTH_BUILD_DIR: osg build directory, place in which you've
-#    built osg via cmake 
+#    built osg via cmake
 
 # Header files are presumed to be included like
 # #include <osgEarth/Common>
@@ -27,15 +27,7 @@
         $ENV{OSGEARTHDIR}
         $ENV{OSGEARTH_DIR}
         $ENV{OSGEO4W_ROOT}
-        /usr/local/
-        /usr/
-        /sw/ # Fink
-        /opt/local/ # DarwinPorts
-        /opt/csw/ # Blastwave
-        /opt/
-        [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSGEARTH_ROOT]/
-        ~/Library/Frameworks
-        /Library/Frameworks
+        @PREFIX@ # Fink
     PATH_SUFFIXES
         /include/
 )
@@ -111,7 +103,7 @@
     SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OSGEARTHUTIL_LIBRARY})
     IF(APPLE)
         # no extra LDFLAGS used in link test, may fail in OS X SDK
-        SET(CMAKE_REQUIRED_LIBRARIES "-F/Library/Frameworks" ${CMAKE_REQUIRED_LIBRARIES})
+        # SET(CMAKE_REQUIRED_LIBRARIES "-F/Library/Frameworks" ${CMAKE_REQUIRED_LIBRARIES})
     ENDIF(APPLE)
     CHECK_CXX_SOURCE_COMPILES("
 #include <osgEarthUtil/Controls>
diff -ruN qgis-2.18.12-orig/cmake/FindPyQt4.cmake qgis-2.18.12/cmake/FindPyQt4.cmake
--- qgis-2.18.12-orig/cmake/FindPyQt4.cmake	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/cmake/FindPyQt4.cmake	2021-04-11 01:26:08.000000000 -0400
@@ -36,7 +36,12 @@
     STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT4_VERSION_TAG ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_version_num:([^\n]+).*$" "\\1" PYQT4_VERSION_NUM ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_mod_dir:([^\n]+).*$" "\\1" PYQT4_MOD_DIR ${pyqt_config})
-    STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT4_SIP_DIR ${pyqt_config})
+    # Fink needs a special path for SIP_DIR, so we allow overriding by -D flag while
+    # auto-determining the rest
+    IF(PYQT4_SIP_DIR)
+    ELSE(PYQT4_SIP_DIR)
+      STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT4_SIP_DIR ${pyqt_config})
+    ENDIF(PYQT4_SIP_DIR)
     STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT4_SIP_FLAGS ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_bin_dir:([^\n]+).*$" "\\1" PYQT4_BIN_DIR ${pyqt_config})
 
diff -ruN qgis-2.18.12-orig/cmake/FindPyQt5.cmake qgis-2.18.12/cmake/FindPyQt5.cmake
--- qgis-2.18.12-orig/cmake/FindPyQt5.cmake	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/cmake/FindPyQt5.cmake	2021-04-11 01:26:02.000000000 -0400
@@ -36,7 +36,12 @@
     STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT5_VERSION_TAG ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_version_num:([^\n]+).*$" "\\1" PYQT5_VERSION_NUM ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_mod_dir:([^\n]+).*$" "\\1" PYQT5_MOD_DIR ${pyqt_config})
-    STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT5_SIP_DIR ${pyqt_config})
+    # Fink needs a special path for SIP_DIR, so we allow overriding by -D flag while
+    # auto-determining the rest
+    IF(PYQT5_SIP_DIR)
+    ELSE(PYQT5_SIP_DIR)
+      STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT5_SIP_DIR ${pyqt_config})
+    ENDIF(PYQT5_SIP_DIR)
     STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT5_SIP_FLAGS ${pyqt_config})
     STRING(REGEX REPLACE ".*\npyqt_bin_dir:([^\n]+).*$" "\\1" PYQT5_BIN_DIR ${pyqt_config})
 
diff -ruN qgis-2.18.12-orig/cmake/FindQScintilla.cmake qgis-2.18.12/cmake/FindQScintilla.cmake
--- qgis-2.18.12-orig/cmake/FindQScintilla.cmake	2017-08-28 16:26:42.000000000 +0900
+++ qgis-2.18.12/cmake/FindQScintilla.cmake	2021-04-10 17:13:32.000000000 -0400
@@ -19,13 +19,13 @@
 # NOTE: include after check for Qt
 
 
-IF(EXISTS QSCINTILLA_VERSION_STR)
+IF(QSCINTILLA_VERSION_STR)
   # Already in cache, be silent
   SET(QSCINTILLA_FOUND TRUE)
-ELSE(EXISTS QSCINTILLA_VERSION_STR)
+ELSE(QSCINTILLA_VERSION_STR)
 
   FIND_PATH(QSCINTILLA_INCLUDE_DIR
-    NAMES Qsci/qsciglobal.h
+    NAMES qsciglobal.h
     PATHS
       ${Qt5Core_INCLUDE_DIRS}
       "${QT_INCLUDE_DIR}"
@@ -62,7 +62,7 @@
   IF(QSCINTILLA_INCLUDE_DIR AND NOT EXISTS QSCINTILLA_VERSION_STR)
     # get QScintilla2 version from header, is optinally retrieved via bindings
     # with Qsci PyQt4 module
-    FILE(READ ${QSCINTILLA_INCLUDE_DIR}/Qsci/qsciglobal.h qsci_header)
+    FILE(READ ${QSCINTILLA_INCLUDE_DIR}/qsciglobal.h qsci_header)
     STRING(REGEX REPLACE "^.*QSCINTILLA_VERSION_STR +\"([^\"]+)\".*$" "\\1" QSCINTILLA_VERSION_STR "${qsci_header}")
   ENDIF(QSCINTILLA_INCLUDE_DIR AND NOT EXISTS QSCINTILLA_VERSION_STR)
 
@@ -76,7 +76,7 @@
     ENDIF(QSCINTILLA_FIND_REQUIRED)
   ENDIF(QSCINTILLA_FOUND)
 
-ENDIF(EXISTS QSCINTILLA_VERSION_STR)
+ENDIF(QSCINTILLA_VERSION_STR)
 
 #MARK_AS_ADVANCED(QSCINTILLA_INCLUDE_DIR QSCINTILLA_LIBRARY)
 
diff -ruN qgis-2.18.12-orig/cmake/FindQsci.cmake qgis-2.18.12/cmake/FindQsci.cmake
--- qgis-2.18.12-orig/cmake/FindQsci.cmake	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/cmake/FindQsci.cmake	2021-04-10 17:14:06.000000000 -0400
@@ -16,10 +16,10 @@
 # Redistribution and use is allowed according to the terms of the BSD license.
 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
-IF(EXISTS QSCI_MOD_VERSION_STR)
+IF(QSCI_MOD_VERSION_STR)
   # Already in cache, be silent
   SET(QSCI_FOUND TRUE)
-ELSE(EXISTS QSCI_MOD_VERSION_STR)
+ELSE(QSCI_MOD_VERSION_STR)
 
   FIND_FILE(_find_qsci_py FindQsci.py PATHS ${CMAKE_MODULE_PATH})
 
@@ -58,4 +58,4 @@
     ENDIF(QSCI_FIND_REQUIRED)
   ENDIF(QSCI_FOUND)
 
-ENDIF(EXISTS QSCI_MOD_VERSION_STR)
+ENDIF(QSCI_MOD_VERSION_STR)
diff -ruN qgis-2.18.12-orig/images/icons/mac/browser/CMakeLists.txt qgis-2.18.12/images/icons/mac/browser/CMakeLists.txt
--- qgis-2.18.12-orig/images/icons/mac/browser/CMakeLists.txt	2017-08-28 16:26:46.000000000 +0900
+++ qgis-2.18.12/images/icons/mac/browser/CMakeLists.txt	2017-08-28 16:30:02.000000000 +0900
@@ -6,4 +6,4 @@
 # create alias now, so alias file gets correct icon, delete first if any exist
 SET (BROWSERNAME "QGIS Browser")
 INSTALL (CODE "EXECUTE_PROCESS(COMMAND /usr/bin/find \"$ENV{DESTDIR}${QGIS_INSTALL_PREFIX}\" -name \"${BROWSERNAME}*\" -maxdepth 1 -type f -delete)")
-INSTALL (CODE "EXECUTE_PROCESS(COMMAND /usr/bin/osascript -e \"tell application \\\"Finder\\\" to make alias file to POSIX file \\\"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${QGIS_BIN_DIR}/${BROWSERNAME}.app\\\" at POSIX file \\\"$ENV{DESTDIR}${QGIS_INSTALL_PREFIX}/\\\"\")")
+#INSTALL (CODE "EXECUTE_PROCESS(COMMAND /usr/bin/osascript -e \"tell application \\\"Finder\\\" to make alias file to POSIX file \\\"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${QGIS_BIN_DIR}/${BROWSERNAME}.app\\\" at POSIX file \\\"$ENV{DESTDIR}${QGIS_INSTALL_PREFIX}/\\\"\")")
diff -ruN qgis-2.18.12-orig/python/PyQt/CMakeLists.txt qgis-2.18.12/python/PyQt/CMakeLists.txt
--- qgis-2.18.12-orig/python/PyQt/CMakeLists.txt	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/python/PyQt/CMakeLists.txt	2021-04-09 08:55:47.000000000 -0400
@@ -16,6 +16,7 @@
   QtSvg.py
   Qsci.py
   Qt.py
+  sip.py
   uic/__init__.py
   uic/pyuic.py
   uic/properties.py
diff -ruN qgis-2.18.12-orig/python/PyQt/PyQt4/sip.py qgis-2.18.12/python/PyQt/PyQt4/sip.py
--- qgis-2.18.12-orig/python/PyQt/PyQt4/sip.py	1969-12-31 19:00:00.000000000 -0500
+++ qgis-2.18.12/python/PyQt/PyQt4/sip.py	2021-04-09 09:09:13.000000000 -0400
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+"""
+***************************************************************************
+    sip.py
+    ---------------------
+    Date                 : October 2018
+    Copyright            : (C) 2018 by Nyall Dawson
+    Email                : nyall dot dawson at gmail dot com
+***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************
+"""
+
+__author__ = 'Nyall Dawson'
+__date__ = 'October 2017'
+__copyright__ = '(C) 2018, Nyall Dawson'
+# This will get replaced with a git SHA1 when you do a git archive
+__revision__ = '$Format:%H$'
+
+try:
+    from PyQt4.sip import *
+except ModuleNotFoundError:
+    from sip import *
diff -ruN qgis-2.18.12-orig/python/PyQt/PyQt5/sip.py qgis-2.18.12/python/PyQt/PyQt5/sip.py
--- qgis-2.18.12-orig/python/PyQt/PyQt5/sip.py	1969-12-31 19:00:00.000000000 -0500
+++ qgis-2.18.12/python/PyQt/PyQt5/sip.py	2021-04-09 08:50:24.000000000 -0400
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+"""
+***************************************************************************
+    sip.py
+    ---------------------
+    Date                 : October 2018
+    Copyright            : (C) 2018 by Nyall Dawson
+    Email                : nyall dot dawson at gmail dot com
+***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************
+"""
+
+__author__ = 'Nyall Dawson'
+__date__ = 'October 2017'
+__copyright__ = '(C) 2018, Nyall Dawson'
+# This will get replaced with a git SHA1 when you do a git archive
+__revision__ = '$Format:%H$'
+
+try:
+    from PyQt5.sip import *
+except ModuleNotFoundError:
+    from sip import *
diff -ruN qgis-2.18.12-orig/python/core/qgscoordinatetransform.sip qgis-2.18.12/python/core/qgscoordinatetransform.sip
--- qgis-2.18.12-orig/python/core/qgscoordinatetransform.sip	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/python/core/qgscoordinatetransform.sip	2021-04-07 19:37:31.000000000 -0400
@@ -15,7 +15,6 @@
 class QgsCoordinateTransform : QObject
 {
 %TypeHeaderCode
-extern PyObject *sipExportedExceptions__core[2];  // workaround: sipExportedExceptions__core is only defined in the first sip part
 #include <qgscoordinatetransform.h>
 %End
 
diff -ruN qgis-2.18.12-orig/python/plugins/processing/algs/grass/GrassUtils.py qgis-2.18.12/python/plugins/processing/algs/grass/GrassUtils.py
--- qgis-2.18.12-orig/python/plugins/processing/algs/grass/GrassUtils.py	2017-08-28 16:26:54.000000000 +0900
+++ qgis-2.18.12/python/plugins/processing/algs/grass/GrassUtils.py	2017-08-28 16:30:02.000000000 +0900
@@ -84,28 +84,7 @@
 
     @staticmethod
     def grassPath():
-        if not isWindows() and not isMac():
-            return ''
-
-        folder = ProcessingConfig.getSetting(GrassUtils.GRASS_FOLDER) or ''
-        if not os.path.exists(folder):
-            folder = None
-        if folder is None:
-            if isWindows():
-                if "OSGEO4W_ROOT" in os.environ:
-                    testfolder = os.path.join(unicode(os.environ['OSGEO4W_ROOT']), "apps")
-                else:
-                    testfolder = unicode(QgsApplication.prefixPath())
-                testfolder = os.path.join(testfolder, 'grass')
-                if os.path.isdir(testfolder):
-                    for subfolder in os.listdir(testfolder):
-                        if subfolder.startswith('grass-6'):
-                            folder = os.path.join(testfolder, subfolder)
-                            break
-            else:
-                folder = os.path.join(QgsApplication.prefixPath(), 'grass')
-                if not os.path.isdir(folder):
-                    folder = '/Applications/GRASS-6.4.app/Contents/MacOS'
+        folder = '@PREFIX@/Applications/GRASS-6.4.app/Contents/MacOS'
 
         if folder:
             ProcessingConfig.setSettingValue(GrassUtils.GRASS_FOLDER, folder)
@@ -252,26 +231,17 @@
     def prepareGrassExecution(commands):
         env = os.environ.copy()
 
-        if isWindows():
-            GrassUtils.createGrassScript(commands)
-            command = ['cmd.exe', '/C ', GrassUtils.grassScriptFilename()]
-        else:
-            gisrc = userFolder() + os.sep + 'processing.gisrc'
-            env['GISRC'] = gisrc
-            env['GRASS_MESSAGE_FORMAT'] = 'gui'
-            env['GRASS_BATCH_JOB'] = GrassUtils.grassBatchJobFilename()
-            if 'GISBASE' in env:
-                del env['GISBASE']
-            GrassUtils.createGrassBatchJobFileFromGrassCommands(commands)
-            os.chmod(GrassUtils.grassBatchJobFilename(), stat.S_IEXEC
-                     | stat.S_IREAD | stat.S_IWRITE)
-            if isMac():
-                command = GrassUtils.grassPath() + os.sep + 'grass.sh ' \
-                    + GrassUtils.grassMapsetFolder() + '/PERMANENT'
-            else:
-                command = 'grass64 ' + GrassUtils.grassMapsetFolder() \
-                    + '/PERMANENT'
-
+        gisrc = userFolder() + os.sep + 'processing.gisrc'
+        env['GISRC'] = gisrc
+        env['GRASS_MESSAGE_FORMAT'] = 'gui'
+        env['GRASS_BATCH_JOB'] = GrassUtils.grassBatchJobFilename()
+        if 'GISBASE' in env:
+            del env['GISBASE']
+        GrassUtils.createGrassBatchJobFileFromGrassCommands(commands)
+        os.chmod(GrassUtils.grassBatchJobFilename(), stat.S_IEXEC
+                 | stat.S_IREAD | stat.S_IWRITE)
+        command = GrassUtils.grassPath() + os.sep + 'grass.sh ' \
+                + GrassUtils.grassMapsetFolder() + '/PERMANENT'
         return command, env
 
     @staticmethod
diff -ruN qgis-2.18.12-orig/python/plugins/processing/algs/grass7/Grass7Utils.py qgis-2.18.12/python/plugins/processing/algs/grass7/Grass7Utils.py
--- qgis-2.18.12-orig/python/plugins/processing/algs/grass7/Grass7Utils.py	2017-08-28 16:26:55.000000000 +0900
+++ qgis-2.18.12/python/plugins/processing/algs/grass7/Grass7Utils.py	2017-08-28 16:30:02.000000000 +0900
@@ -107,38 +107,7 @@
 
     @staticmethod
     def grassPath():
-        if not isWindows() and not isMac():
-            return ''
-
-        folder = ProcessingConfig.getSetting(Grass7Utils.GRASS_FOLDER) or ''
-        if not os.path.exists(folder):
-            folder = None
-        if folder is None:
-            if isWindows():
-                if "OSGEO4W_ROOT" in os.environ:
-                    testfolder = os.path.join(unicode(os.environ['OSGEO4W_ROOT']), "apps")
-                else:
-                    testfolder = unicode(QgsApplication.prefixPath())
-                testfolder = os.path.join(testfolder, 'grass')
-                if os.path.isdir(testfolder):
-                    for subfolder in os.listdir(testfolder):
-                        if subfolder.startswith('grass-7'):
-                            folder = os.path.join(testfolder, subfolder)
-                            fn = os.path.join(folder, "etc", "VERSIONNUMBER")
-                            if not os.path.isfile(fn):
-                                continue
-
-                            f = open(fn, "r")
-                            Grass7Utils.version = f.read().split(' ')[0]
-                            f.close()
-
-                            major, minor, patch = Grass7Utils.version.split('.')
-                            Grass7Utils.command = "grass{}{}".format(major, minor)
-                            break
-            else:
-                folder = os.path.join(unicode(QgsApplication.prefixPath()), 'grass7')
-                if not os.path.isdir(folder):
-                    folder = '/Applications/GRASS-7.0.app/Contents/MacOS'
+        folder = '@PREFIX@/Applications/GRASS-mac-7.2.app/Contents/MacOS'
 
         return folder or ''
 
@@ -448,7 +417,7 @@
                 if os.path.exists(localPath):
                     helpPath = os.path.abspath(localPath)
             elif isMac():
-                localPath = '/Applications/GRASS-7.0.app/Contents/MacOS/docs/html'
+                localPath = '@PREFIX@/Applications/GRASS-mac-7.2.app/Contents/MacOS/docs/html'
                 if os.path.exists(localPath):
                     helpPath = os.path.abspath(localPath)
             else:
diff -ruN qgis-2.18.12-orig/python/plugins/processing/algs/saga/SagaUtils.py qgis-2.18.12/python/plugins/processing/algs/saga/SagaUtils.py
--- qgis-2.18.12-orig/python/plugins/processing/algs/saga/SagaUtils.py	2017-08-28 16:26:57.000000000 +0900
+++ qgis-2.18.12/python/plugins/processing/algs/saga/SagaUtils.py	2017-08-28 16:34:29.000000000 +0900
@@ -58,7 +58,7 @@
 def findSagaFolder():
     folder = None
     if isMac():
-        testfolder = os.path.join(QgsApplication.prefixPath(), 'bin')
+        testfolder = '@PREFIX@/bin'
         if os.path.exists(os.path.join(testfolder, 'saga_cmd')):
             folder = testfolder
         else:
diff -ruN qgis-2.18.12-orig/src/analysis/raster/qgsalignraster.cpp qgis-2.18.12/src/analysis/raster/qgsalignraster.cpp
--- qgis-2.18.12-orig/src/analysis/raster/qgsalignraster.cpp	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/analysis/raster/qgsalignraster.cpp	2021-04-07 19:13:26.000000000 -0400
@@ -16,7 +16,7 @@
 #include "qgsalignraster.h"
 
 #include <gdalwarper.h>
-#include <ogr_spatialref.h>
+#include <ogr_srs_api.h>
 #include <cpl_conv.h>
 #include <limits>
 
diff -ruN qgis-2.18.12-orig/src/core/CMakeLists.txt qgis-2.18.12/src/core/CMakeLists.txt
--- qgis-2.18.12-orig/src/core/CMakeLists.txt	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/core/CMakeLists.txt	2021-04-07 14:28:17.000000000 -0400
@@ -366,9 +366,9 @@
 
 
 FILE(GLOB JSON_HELP_FILES "${CMAKE_SOURCE_DIR}/resources/function_help/json/*")
-IF(NOT USING_NINJA)
+IF(CMAKE_VERSION VERSION_LESS "3.18" AND NOT USING_NINJA)
   STRING(REPLACE "$" "$$" JSON_HELP_FILES "${JSON_HELP_FILES}")
-ENDIF(NOT USING_NINJA)
+ENDIF(CMAKE_VERSION VERSION_LESS "3.18" AND NOT USING_NINJA)
 STRING(REPLACE "\(" "\\(" JSON_HELP_FILES "${JSON_HELP_FILES}")
 STRING(REPLACE "\)" "\\)" JSON_HELP_FILES "${JSON_HELP_FILES}")
 ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qgsexpression_texts.cpp
diff -ruN qgis-2.18.12-orig/src/core/qgsdataitem.cpp qgis-2.18.12/src/core/qgsdataitem.cpp
--- qgis-2.18.12-orig/src/core/qgsdataitem.cpp	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/core/qgsdataitem.cpp	2021-04-07 19:13:26.000000000 -0400
@@ -40,6 +40,7 @@
 #include "qgsconfig.h"
 
 // use GDAL VSI mechanism
+#define CPL_SUPRESS_CPLUSPLUS
 #include "cpl_vsi.h"
 #include "cpl_string.h"
 
@@ -1301,7 +1302,7 @@
   char **papszFiles1 = nullptr;
   char **papszFiles2 = nullptr;
   VSIStatBufL psStatBuf;
-  CPLString osTemp1, osTemp2;
+  QString temp1, temp2;
   int i, j;
   int nCount1, nCount2;
 
@@ -1315,41 +1316,35 @@
   for ( i = 0; i < nCount1; i++ )
   {
     // build complete file name for stat
-    osTemp1.clear();
-    osTemp1.append( pszPath );
-    osTemp1.append( "/" );
-    osTemp1.append( papszFiles1[i] );
+    temp1 = QString( "%1/%2" ).arg( pszPath, papszFiles1[i] );
 
     // if is file, add it
-    if ( VSIStatL( osTemp1.c_str(), &psStatBuf ) == 0 &&
+    if ( VSIStatL( temp1.toUtf8(), &psStatBuf ) == 0 &&
          VSI_ISREG( psStatBuf.st_mode ) )
     {
       // oFiles.AddString( papszFiles1[i] );
       papszOFiles = CSLAddString( papszOFiles, papszFiles1[i] );
     }
-    else if ( VSIStatL( osTemp1.c_str(), &psStatBuf ) == 0 &&
+    else if ( VSIStatL( temp1.toUtf8(), &psStatBuf ) == 0 &&
               VSI_ISDIR( psStatBuf.st_mode ) )
     {
       // add directory entry
-      osTemp2.clear();
-      osTemp2.append( papszFiles1[i] );
-      osTemp2.append( "/" );
-      // oFiles.AddString( osTemp2.c_str() );
-      papszOFiles = CSLAddString( papszOFiles, osTemp2.c_str() );
+      temp2 = QString( "%1/" ).arg( papszFiles1[i] );
+
+      // oFiles.AddString( temp2.toUtf8() );
+      papszOFiles = CSLAddString( papszOFiles, temp2.toUtf8() );
 
       // recursively add files inside directory
-      papszFiles2 = VSIReadDirRecursive1( osTemp1.c_str() );
+      papszFiles2 = VSIReadDirRecursive1( temp1.toUtf8() );
       if ( papszFiles2 )
       {
         nCount2 = CSLCount( papszFiles2 );
         for ( j = 0; j < nCount2; j++ )
         {
-          osTemp2.clear();
-          osTemp2.append( papszFiles1[i] );
-          osTemp2.append( "/" );
-          osTemp2.append( papszFiles2[j] );
-          // oFiles.AddString( osTemp2.c_str() );
-          papszOFiles = CSLAddString( papszOFiles, osTemp2.c_str() );
+          temp2 = QString( "%1/%2" ).arg( papszFiles1[i], papszFiles2[j] );
+
+          // oFiles.AddString( temp2.toUtf8() );
+          papszOFiles = CSLAddString( papszOFiles, temp2.toUtf8() );
         }
         CSLDestroy( papszFiles2 );
       }
diff -ruN qgis-2.18.12-orig/src/providers/gdal/qgsgdalprovider.cpp qgis-2.18.12/src/providers/gdal/qgsgdalprovider.cpp
--- qgis-2.18.12-orig/src/providers/gdal/qgsgdalprovider.cpp	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/providers/gdal/qgsgdalprovider.cpp	2021-04-07 19:30:28.000000000 -0400
@@ -49,7 +49,7 @@
 #include <QDebug>
 
 #include "gdalwarper.h"
-#include "ogr_spatialref.h"
+#include "ogr_srs_api.h"
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
diff -ruN qgis-2.18.12-orig/src/providers/wcs/qgswcsprovider.cpp qgis-2.18.12/src/providers/wcs/qgswcsprovider.cpp
--- qgis-2.18.12-orig/src/providers/wcs/qgswcsprovider.cpp	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/providers/wcs/qgswcsprovider.cpp	2021-04-07 19:13:26.000000000 -0400
@@ -45,7 +45,7 @@
 #endif
 
 #include "gdalwarper.h"
-#include "ogr_spatialref.h"
+#include "ogr_srs_api.h"
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
diff -ruN qgis-2.18.12-orig/src/providers/wms/CMakeLists.txt qgis-2.18.12/src/providers/wms/CMakeLists.txt
--- qgis-2.18.12-orig/src/providers/wms/CMakeLists.txt	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/providers/wms/CMakeLists.txt	2021-04-10 09:25:22.000000000 -0400
@@ -41,6 +41,7 @@
   ${GEOS_INCLUDE_DIR}
   ${QT_QTSCRIPT_INCLUDE_DIR}
   ${QCA_INCLUDE_DIR}
+  ${EXPAT_INCLUDE_DIR}
 )
 
 ADD_LIBRARY(wmsprovider_a STATIC ${WMS_SRCS} ${WMS_MOC_SRCS})
@@ -51,6 +52,7 @@
   qgis_gui
   ${QT_QTSCRIPT_LIBRARY}
   ${GDAL_LIBRARY}  # for OGR_G_CreateGeometryFromJson()
+  ${EXPAT_LIBRARY}
 )
 
 TARGET_LINK_LIBRARIES(wmsprovider_a
diff -ruN qgis-2.18.12-orig/src/python/qgspythonutilsimpl.cpp qgis-2.18.12/src/python/qgspythonutilsimpl.cpp
--- qgis-2.18.12-orig/src/python/qgspythonutilsimpl.cpp	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/src/python/qgspythonutilsimpl.cpp	2021-04-09 09:07:30.000000000 -0400
@@ -122,7 +122,7 @@
   runString( "sys.path = [" + newpaths.join( "," ) + "] + sys.path" );
 
   // import SIP
-  if ( !runString( "import sip",
+  if ( !runString( "from qgis.PyQt import sip",
                    QObject::tr( "Couldn't load SIP module." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) )
   {
     return false;
diff -ruN qgis-2.18.12-orig/tests/src/python/test_qgsmaplayerregistry.py qgis-2.18.12/tests/src/python/test_qgsmaplayerregistry.py
--- qgis-2.18.12-orig/tests/src/python/test_qgsmaplayerregistry.py	2017-08-18 08:31:22.000000000 -0400
+++ qgis-2.18.12/tests/src/python/test_qgsmaplayerregistry.py	2021-04-09 09:07:13.000000000 -0400
@@ -15,7 +15,7 @@
 from qgis.core import QgsMapLayerRegistry, QgsVectorLayer, QgsMapLayer
 from qgis.testing import start_app, unittest
 from qgis.PyQt.QtCore import QT_VERSION_STR
-import sip
+from qgis.PyQt import sip
 
 try:
     from qgis.PyQt.QtTest import QSignalSpy
