Skip to content

Commit b5be69f

Browse files
author
wonder
committedJan 16, 2010
Native and faster compilation of python bindings (#2370)
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12774 c8812cc2-4d05-0410-92ff-de0c093fc19c

16 files changed

+613
-585
lines changed
 

‎CMakeLists.txt

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,6 @@ IF (WITH_SPATIALITE AND NOT WITH_INTERNAL_SPATIALITE)
157157
FIND_PACKAGE(SPATIALITE)
158158
ENDIF (WITH_SPATIALITE AND NOT WITH_INTERNAL_SPATIALITE)
159159

160-
IF (WITH_BINDINGS)
161-
# python support:
162-
# - mapserver export tool
163-
# - bindings
164-
INCLUDE (Python) # file cmake/Python.cmake
165-
ENDIF (WITH_BINDINGS)
166-
167160
IF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)
168161
MESSAGE (SEND_ERROR "Some dependencies were not found!")
169162
ENDIF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)
@@ -350,6 +343,32 @@ IF (UNIX)
350343
SET (QGIS_MANUAL_DIR ${CMAKE_INSTALL_PREFIX}/${QGIS_MANUAL_SUBDIR})
351344
ENDIF (UNIX)
352345

346+
#############################################################
347+
# Python bindings
348+
349+
IF (WITH_BINDINGS)
350+
351+
# python support: check for interpreter, sip, pyqt4
352+
FIND_PACKAGE(PythonInterp REQUIRED)
353+
FIND_PACKAGE(PythonLibrary REQUIRED)
354+
FIND_PACKAGE(SIP REQUIRED)
355+
FIND_PACKAGE(PyQt4 REQUIRED)
356+
INCLUDE(PythonMacros)
357+
INCLUDE(SIPMacros)
358+
INCLUDE(PyQt4Macros)
359+
360+
# setup SIP variables
361+
separate_arguments(PYQT4_SIP_FLAGS) # convert space separated values to a list
362+
set(SIP_INCLUDES ${PYQT4_SIP_DIR} ${CMAKE_SOURCE_DIR}/python)
363+
set(SIP_CONCAT_PARTS 4)
364+
set(SIP_EXTRA_OPTIONS ${PYQT4_SIP_FLAGS})
365+
366+
IF (NOT BINDINGS_GLOBAL_INSTALL)
367+
set(PYTHON_SITE_PACKAGES_DIR ${QGIS_DATA_DIR}/python)
368+
ENDIF (NOT BINDINGS_GLOBAL_INSTALL)
369+
370+
ENDIF (WITH_BINDINGS)
371+
353372
#############################################################
354373
# create qgsconfig.h
355374

@@ -401,11 +420,9 @@ ADD_CUSTOM_TARGET(svnversion ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qgssvnversi
401420

402421
SUBDIRS(src doc images resources i18n)
403422

404-
IF (HAVE_PYTHON AND WITH_BINDINGS)
423+
IF (WITH_BINDINGS)
405424
SUBDIRS (python)
406-
ELSE (HAVE_PYTHON AND WITH_BINDINGS)
407-
MESSAGE (STATUS "Python not being built")
408-
ENDIF (HAVE_PYTHON AND WITH_BINDINGS)
425+
ENDIF (WITH_BINDINGS)
409426

410427
IF (ENABLE_TESTS)
411428
#create a variable to specify where our test data is

‎cmake/FindLibPython.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
3+
# Redistribution and use is allowed according to the terms of the BSD license.
4+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
5+
6+
import sys
7+
import distutils.sysconfig
8+
9+
print("exec_prefix:%s" % sys.exec_prefix)
10+
print("short_version:%s" % sys.version[:3])
11+
print("long_version:%s" % sys.version.split()[0])
12+
print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc())
13+
print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1))

‎cmake/FindPyQt.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
2+
# Redistribution and use is allowed according to the terms of the BSD license.
3+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
4+
5+
import PyQt4.pyqtconfig
6+
7+
pyqtcfg = PyQt4.pyqtconfig.Configuration()
8+
print("pyqt_version:%06.0x" % pyqtcfg.pyqt_version)
9+
print("pyqt_version_str:%s" % pyqtcfg.pyqt_version_str)
10+
11+
pyqt_version_tag = ""
12+
in_t = False
13+
for item in pyqtcfg.pyqt_sip_flags.split(' '):
14+
if item=="-t":
15+
in_t = True
16+
elif in_t:
17+
if item.startswith("Qt_4"):
18+
pyqt_version_tag = item
19+
else:
20+
in_t = False
21+
print("pyqt_version_tag:%s" % pyqt_version_tag)
22+
23+
print("pyqt_sip_dir:%s" % pyqtcfg.pyqt_sip_dir)
24+
print("pyqt_sip_flags:%s" % pyqtcfg.pyqt_sip_flags)

‎cmake/FindPyQt4.cmake

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Find PyQt4
2+
# ~~~~~~~~~~
3+
# Copyright (c) 2007-2008, Simon Edwards <simon@simonzone.com>
4+
# Redistribution and use is allowed according to the terms of the BSD license.
5+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
6+
#
7+
# PyQt4 website: http://www.riverbankcomputing.co.uk/pyqt/index.php
8+
#
9+
# Find the installed version of PyQt4. FindPyQt4 should only be called after
10+
# Python has been found.
11+
#
12+
# This file defines the following variables:
13+
#
14+
# PYQT4_VERSION - The version of PyQt4 found expressed as a 6 digit hex number
15+
# suitable for comparision as a string
16+
#
17+
# PYQT4_VERSION_STR - The version of PyQt4 as a human readable string.
18+
#
19+
# PYQT4_VERSION_TAG - The PyQt version tag using by PyQt's sip files.
20+
#
21+
# PYQT4_SIP_DIR - The directory holding the PyQt4 .sip files.
22+
#
23+
# PYQT4_SIP_FLAGS - The SIP flags used to build PyQt.
24+
25+
IF(EXISTS PYQT4_VERSION)
26+
# Already in cache, be silent
27+
SET(PYQT4_FOUND TRUE)
28+
ELSE(EXISTS PYQT4_VERSION)
29+
30+
FIND_FILE(_find_pyqt_py FindPyQt.py PATHS ${CMAKE_MODULE_PATH})
31+
32+
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} OUTPUT_VARIABLE pyqt_config)
33+
IF(pyqt_config)
34+
STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT4_VERSION ${pyqt_config})
35+
STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT4_VERSION_STR ${pyqt_config})
36+
STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT4_VERSION_TAG ${pyqt_config})
37+
STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT4_SIP_DIR ${pyqt_config})
38+
STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT4_SIP_FLAGS ${pyqt_config})
39+
40+
SET(PYQT4_FOUND TRUE)
41+
ENDIF(pyqt_config)
42+
43+
IF(PYQT4_FOUND)
44+
IF(NOT PYQT4_FIND_QUIETLY)
45+
MESSAGE(STATUS "Found PyQt4 version: ${PYQT4_VERSION_STR}")
46+
ENDIF(NOT PYQT4_FIND_QUIETLY)
47+
ELSE(PYQT4_FOUND)
48+
IF(PYQT4_FIND_REQUIRED)
49+
MESSAGE(FATAL_ERROR "Could not find Python")
50+
ENDIF(PYQT4_FIND_REQUIRED)
51+
ENDIF(PYQT4_FOUND)
52+
53+
ENDIF(EXISTS PYQT4_VERSION)

‎cmake/FindPythonLibrary.cmake

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Find Python
2+
# ~~~~~~~~~~~
3+
# Find the Python interpreter and related Python directories.
4+
#
5+
# This file defines the following variables:
6+
#
7+
# PYTHON_EXECUTABLE - The path and filename of the Python interpreter.
8+
#
9+
# PYTHON_SHORT_VERSION - The version of the Python interpreter found,
10+
# excluding the patch version number. (e.g. 2.5 and not 2.5.1))
11+
#
12+
# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human
13+
# readable string.
14+
#
15+
# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory.
16+
#
17+
# PYTHON_INCLUDE_PATH - Directory holding the python.h include file.
18+
#
19+
# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library.
20+
21+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
22+
# Redistribution and use is allowed according to the terms of the BSD license.
23+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
24+
25+
26+
27+
INCLUDE(CMakeFindFrameworks)
28+
29+
if(EXISTS PYTHON_LIBRARY)
30+
# Already in cache, be silent
31+
set(PYTHONLIBRARY_FOUND TRUE)
32+
else(EXISTS PYTHON_LIBRARY)
33+
34+
FIND_PACKAGE(PythonInterp)
35+
36+
if(PYTHONINTERP_FOUND)
37+
38+
FIND_FILE(_find_lib_python_py FindLibPython.py PATHS ${CMAKE_MODULE_PATH})
39+
40+
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_lib_python_py} OUTPUT_VARIABLE python_config)
41+
if(python_config)
42+
STRING(REGEX REPLACE ".*exec_prefix:([^\n]+).*$" "\\1" PYTHON_PREFIX ${python_config})
43+
STRING(REGEX REPLACE ".*\nshort_version:([^\n]+).*$" "\\1" PYTHON_SHORT_VERSION ${python_config})
44+
STRING(REGEX REPLACE ".*\nlong_version:([^\n]+).*$" "\\1" PYTHON_LONG_VERSION ${python_config})
45+
STRING(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_PATH ${python_config})
46+
if(NOT PYTHON_SITE_PACKAGES_DIR)
47+
if(NOT PYTHON_LIBS_WITH_KDE_LIBS)
48+
STRING(REGEX REPLACE ".*\nsite_packages_dir:([^\n]+).*$" "\\1" PYTHON_SITE_PACKAGES_DIR ${python_config})
49+
else(NOT PYTHON_LIBS_WITH_KDE_LIBS)
50+
set(PYTHON_SITE_PACKAGES_DIR ${KDE4_LIB_INSTALL_DIR}/python${PYTHON_SHORT_VERSION}/site-packages)
51+
endif(NOT PYTHON_LIBS_WITH_KDE_LIBS)
52+
endif(NOT PYTHON_SITE_PACKAGES_DIR)
53+
STRING(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_SHORT_VERSION_NO_DOT ${PYTHON_SHORT_VERSION})
54+
set(PYTHON_LIBRARY_NAMES python${PYTHON_SHORT_VERSION} python${PYTHON_SHORT_VERSION_NO_DOT})
55+
if(WIN32)
56+
STRING(REPLACE "\\" "/" PYTHON_SITE_PACKAGES_DIR ${PYTHON_SITE_PACKAGES_DIR})
57+
endif(WIN32)
58+
FIND_LIBRARY(PYTHON_LIBRARY NAMES ${PYTHON_LIBRARY_NAMES} PATHS ${PYTHON_PREFIX}/lib ${PYTHON_PREFIX}/libs NO_DEFAULT_PATH)
59+
set(PYTHONLIBRARY_FOUND TRUE)
60+
endif(python_config)
61+
62+
# adapted from cmake's builtin FindPythonLibs
63+
if(APPLE)
64+
CMAKE_FIND_FRAMEWORKS(Python)
65+
set(PYTHON_FRAMEWORK_INCLUDES)
66+
if(Python_FRAMEWORKS)
67+
# If a framework has been selected for the include path,
68+
# make sure "-framework" is used to link it.
69+
if("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
70+
set(PYTHON_LIBRARY "")
71+
set(PYTHON_DEBUG_LIBRARY "")
72+
endif("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
73+
if(NOT PYTHON_LIBRARY)
74+
set (PYTHON_LIBRARY "-framework Python" CACHE FILEPATH "Python Framework" FORCE)
75+
endif(NOT PYTHON_LIBRARY)
76+
set(PYTHONLIBRARY_FOUND TRUE)
77+
endif(Python_FRAMEWORKS)
78+
endif(APPLE)
79+
endif(PYTHONINTERP_FOUND)
80+
81+
if(PYTHONLIBRARY_FOUND)
82+
set(PYTHON_LIBRARIES ${PYTHON_LIBRARY})
83+
if(NOT PYTHONLIBRARY_FIND_QUIETLY)
84+
message(STATUS "Found Python executable: ${PYTHON_EXECUTABLE}")
85+
message(STATUS "Found Python version: ${PYTHON_LONG_VERSION}")
86+
message(STATUS "Found Python library: ${PYTHON_LIBRARY}")
87+
endif(NOT PYTHONLIBRARY_FIND_QUIETLY)
88+
else(PYTHONLIBRARY_FOUND)
89+
if(PYTHONLIBRARY_FIND_REQUIRED)
90+
message(FATAL_ERROR "Could not find Python")
91+
endif(PYTHONLIBRARY_FIND_REQUIRED)
92+
endif(PYTHONLIBRARY_FOUND)
93+
94+
endif (EXISTS PYTHON_LIBRARY)

‎cmake/FindSIP.cmake

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Find SIP
2+
# ~~~~~~~~
3+
#
4+
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
5+
#
6+
# Find the installed version of SIP. FindSIP should be called after Python
7+
# has been found.
8+
#
9+
# This file defines the following variables:
10+
#
11+
# SIP_VERSION - The version of SIP found expressed as a 6 digit hex number
12+
# suitable for comparision as a string.
13+
#
14+
# SIP_VERSION_STR - The version of SIP found as a human readable string.
15+
#
16+
# SIP_EXECUTABLE - Path and filename of the SIP command line executable.
17+
#
18+
# SIP_INCLUDE_DIR - Directory holding the SIP C++ header file.
19+
#
20+
# SIP_DEFAULT_SIP_DIR - Default directory where .sip files should be installed
21+
# into.
22+
23+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
24+
# Redistribution and use is allowed according to the terms of the BSD license.
25+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
26+
27+
28+
29+
IF(SIP_VERSION)
30+
# Already in cache, be silent
31+
SET(SIP_FOUND TRUE)
32+
ELSE(SIP_VERSION)
33+
34+
FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
35+
36+
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_sip_py} OUTPUT_VARIABLE sip_config)
37+
IF(sip_config)
38+
STRING(REGEX REPLACE "^sip_version:([^\n]+).*$" "\\1" SIP_VERSION ${sip_config})
39+
STRING(REGEX REPLACE ".*\nsip_version_str:([^\n]+).*$" "\\1" SIP_VERSION_STR ${sip_config})
40+
STRING(REGEX REPLACE ".*\nsip_bin:([^\n]+).*$" "\\1" SIP_EXECUTABLE ${sip_config})
41+
STRING(REGEX REPLACE ".*\ndefault_sip_dir:([^\n]+).*$" "\\1" SIP_DEFAULT_SIP_DIR ${sip_config})
42+
STRING(REGEX REPLACE ".*\nsip_inc_dir:([^\n]+).*$" "\\1" SIP_INCLUDE_DIR ${sip_config})
43+
SET(SIP_FOUND TRUE)
44+
ENDIF(sip_config)
45+
46+
IF(SIP_FOUND)
47+
IF(NOT SIP_FIND_QUIETLY)
48+
MESSAGE(STATUS "Found SIP version: ${SIP_VERSION_STR}")
49+
ENDIF(NOT SIP_FIND_QUIETLY)
50+
ELSE(SIP_FOUND)
51+
IF(SIP_FIND_REQUIRED)
52+
MESSAGE(FATAL_ERROR "Could not find SIP")
53+
ENDIF(SIP_FIND_REQUIRED)
54+
ENDIF(SIP_FOUND)
55+
56+
ENDIF(SIP_VERSION)

‎cmake/FindSIP.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# FindSIP.py
2+
#
3+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
4+
# Redistribution and use is allowed according to the terms of the BSD license.
5+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
6+
7+
import sys
8+
import sipconfig
9+
10+
sipcfg = sipconfig.Configuration()
11+
print("sip_version:%06.0x" % sipcfg.sip_version)
12+
print("sip_version_str:%s" % sipcfg.sip_version_str)
13+
print("sip_bin:%s" % sipcfg.sip_bin)
14+
print("default_sip_dir:%s" % sipcfg.default_sip_dir)
15+
print("sip_inc_dir:%s" % sipcfg.sip_inc_dir)

‎cmake/PyQt4Macros.cmake

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
3+
IF(NOT PYUIC4_PROGRAM)
4+
IF (MSVC)
5+
FIND_PROGRAM(PYUIC4_PROGRAM
6+
NAMES pyuic4.bat
7+
PATHS $ENV{LIB_DIR}/bin
8+
)
9+
ELSE(MSVC)
10+
FIND_PROGRAM(PYUIC4_PROGRAM pyuic4)
11+
ENDIF (MSVC)
12+
13+
IF (NOT PYUIC4_PROGRAM)
14+
MESSAGE(FATAL_ERROR "pyuic4 not found - aborting")
15+
ENDIF (NOT PYUIC4_PROGRAM)
16+
ENDIF(NOT PYUIC4_PROGRAM)
17+
18+
# Adapted from QT4_WRAP_UI
19+
MACRO(PYQT4_WRAP_UI outfiles )
20+
FOREACH(it ${ARGN})
21+
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
22+
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
23+
SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py)
24+
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
25+
COMMAND ${PYUIC4_PROGRAM} ${infile} -o ${outfile}
26+
MAIN_DEPENDENCY ${infile}
27+
)
28+
SET(${outfiles} ${${outfiles}} ${outfile})
29+
ENDFOREACH(it)
30+
ENDMACRO(PYQT4_WRAP_UI)
31+
32+
IF(NOT PYRCC4_PROGRAM)
33+
IF (MSVC)
34+
FIND_PROGRAM(PYRCC4_PROGRAM
35+
NAMES pyrcc4.exe
36+
PATHS $ENV{LIB_DIR}/bin
37+
)
38+
ELSE(MSVC)
39+
FIND_PROGRAM(PYRCC4_PROGRAM pyrcc4)
40+
ENDIF (MSVC)
41+
42+
IF (NOT PYRCC4_PROGRAM)
43+
MESSAGE(FATAL_ERROR "pyrcc4 not found - aborting")
44+
ENDIF (NOT PYRCC4_PROGRAM)
45+
ENDIF(NOT PYRCC4_PROGRAM)
46+
47+
# Adapted from QT4_ADD_RESOURCES
48+
MACRO (PYQT4_ADD_RESOURCES outfiles )
49+
FOREACH (it ${ARGN})
50+
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
51+
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
52+
GET_FILENAME_COMPONENT(rc_path ${infile} PATH)
53+
SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py)
54+
# parse file for dependencies
55+
# all files are absolute paths or relative to the location of the qrc file
56+
FILE(READ "${infile}" _RC_FILE_CONTENTS)
57+
STRING(REGEX MATCHALL "<file[^<]+" _RC_FILES "${_RC_FILE_CONTENTS}")
58+
SET(_RC_DEPENDS)
59+
FOREACH(_RC_FILE ${_RC_FILES})
60+
STRING(REGEX REPLACE "^<file[^>]*>" "" _RC_FILE "${_RC_FILE}")
61+
STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}")
62+
IF(NOT _ABS_PATH_INDICATOR)
63+
SET(_RC_FILE "${rc_path}/${_RC_FILE}")
64+
ENDIF(NOT _ABS_PATH_INDICATOR)
65+
SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}")
66+
ENDFOREACH(_RC_FILE)
67+
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
68+
COMMAND ${PYRCC4_PROGRAM} -name ${outfile} -o ${outfile} ${infile}
69+
MAIN_DEPENDENCY ${infile}
70+
DEPENDS ${_RC_DEPENDS})
71+
SET(${outfiles} ${${outfiles}} ${outfile})
72+
ENDFOREACH (it)
73+
ENDMACRO (PYQT4_ADD_RESOURCES)

‎cmake/Python.cmake

Lines changed: 0 additions & 216 deletions
This file was deleted.

‎cmake/PythonCompile.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# By Simon Edwards <simon@simonzone.com>
2+
# This file is in the public domain.
3+
import py_compile
4+
py_compile.main()

‎cmake/PythonMacros.cmake

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Python macros
2+
# ~~~~~~~~~~~~~
3+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
4+
#
5+
# Redistribution and use is allowed according to the terms of the BSD license.
6+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
7+
#
8+
# This file defines the following macros:
9+
#
10+
# PYTHON_INSTALL (SOURCE_FILE DESINATION_DIR)
11+
# Install the SOURCE_FILE, which is a Python .py file, into the
12+
# destination directory during install. The file will be byte compiled
13+
# and both the .py file and .pyc file will be installed.
14+
15+
GET_FILENAME_COMPONENT(PYTHON_MACROS_MODULE_PATH ${CMAKE_CURRENT_LIST_FILE} PATH)
16+
17+
MACRO(PYTHON_INSTALL SOURCE_FILE DESINATION_DIR)
18+
19+
FIND_FILE(_python_compile_py PythonCompile.py PATHS ${CMAKE_MODULE_PATH})
20+
21+
22+
# Install the source file.
23+
INSTALL(FILES ${SOURCE_FILE} DESTINATION ${DESINATION_DIR})
24+
25+
# Byte compile and install the .pyc file.
26+
GET_FILENAME_COMPONENT(_absfilename ${SOURCE_FILE} ABSOLUTE)
27+
GET_FILENAME_COMPONENT(_filename ${SOURCE_FILE} NAME)
28+
GET_FILENAME_COMPONENT(_filenamebase ${SOURCE_FILE} NAME_WE)
29+
GET_FILENAME_COMPONENT(_basepath ${SOURCE_FILE} PATH)
30+
31+
if(WIN32)
32+
string(REGEX REPLACE ".:/" "/" _basepath "${_basepath}")
33+
endif(WIN32)
34+
35+
SET(_bin_py ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filename})
36+
SET(_bin_pyc ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filenamebase}.pyc)
37+
38+
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_basepath})
39+
40+
SET(_message "-DMESSAGE=Byte-compiling ${_bin_py}")
41+
42+
GET_FILENAME_COMPONENT(_abs_bin_py ${_bin_py} ABSOLUTE)
43+
IF(_abs_bin_py STREQUAL ${_absfilename}) # Don't copy the file onto itself.
44+
ADD_CUSTOM_COMMAND(
45+
TARGET compile_python_files
46+
COMMAND ${CMAKE_COMMAND} -E echo ${message}
47+
COMMAND ${PYTHON_EXECUTABLE} ${_python_compile_py} ${_bin_py}
48+
DEPENDS ${_absfilename}
49+
)
50+
ELSE(_abs_bin_py STREQUAL ${_absfilename})
51+
ADD_CUSTOM_COMMAND(
52+
TARGET compile_python_files
53+
COMMAND ${CMAKE_COMMAND} -E echo ${message}
54+
COMMAND ${CMAKE_COMMAND} -E copy ${_absfilename} ${_bin_py}
55+
COMMAND ${PYTHON_EXECUTABLE} ${_python_compile_py} ${_bin_py}
56+
DEPENDS ${_absfilename}
57+
)
58+
ENDIF(_abs_bin_py STREQUAL ${_absfilename})
59+
60+
INSTALL(FILES ${_bin_pyc} DESTINATION ${DESINATION_DIR})
61+
ENDMACRO(PYTHON_INSTALL)

‎cmake/SIPMacros.cmake

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Macros for SIP
2+
# ~~~~~~~~~~~~~~
3+
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
4+
# Redistribution and use is allowed according to the terms of the BSD license.
5+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
6+
#
7+
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
8+
#
9+
# This file defines the following macros:
10+
#
11+
# ADD_SIP_PYTHON_MODULE (MODULE_NAME MODULE_SIP [library1, libaray2, ...])
12+
# Specifies a SIP file to be built into a Python module and installed.
13+
# MODULE_NAME is the name of Python module including any path name. (e.g.
14+
# os.sys, Foo.bar etc). MODULE_SIP the path and filename of the .sip file
15+
# to process and compile. libraryN are libraries that the Python module,
16+
# which is typically a shared library, should be linked to. The built
17+
# module will also be install into Python's site-packages directory.
18+
#
19+
# The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a
20+
# number of variables:
21+
#
22+
# SIP_INCLUDES - List of directories which SIP will scan through when looking
23+
# for included .sip files. (Corresponds to the -I option for SIP.)
24+
#
25+
# SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t
26+
# option for SIP.)
27+
#
28+
# SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code
29+
# of each module should be split into. Defaults to 8. (Corresponds to the
30+
# -j option for SIP.)
31+
#
32+
# SIP_DISABLE_FEATURES - List of feature names which should be disabled
33+
# running SIP. (Corresponds to the -x option for SIP.)
34+
#
35+
# SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to
36+
# SIP.
37+
38+
SET(SIP_INCLUDES)
39+
SET(SIP_TAGS)
40+
SET(SIP_CONCAT_PARTS 8)
41+
SET(SIP_DISABLE_FEATURES)
42+
SET(SIP_EXTRA_OPTIONS)
43+
44+
MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP)
45+
46+
SET(EXTRA_LINK_LIBRARIES ${ARGN})
47+
48+
STRING(REPLACE "." "/" _x ${MODULE_NAME})
49+
GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH)
50+
GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME)
51+
52+
GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH)
53+
GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE)
54+
55+
# We give this target a long logical target name.
56+
# (This is to avoid having the library name clash with any already
57+
# install library names. If that happens then cmake dependancy
58+
# tracking get confused.)
59+
STRING(REPLACE "." "_" _logical_name ${MODULE_NAME})
60+
SET(_logical_name "python_module_${_logical_name}")
61+
62+
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}) # Output goes in this dir.
63+
64+
SET(_sip_includes)
65+
FOREACH (_inc ${SIP_INCLUDES})
66+
GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE)
67+
LIST(APPEND _sip_includes -I ${_abs_inc})
68+
ENDFOREACH (_inc )
69+
70+
SET(_sip_tags)
71+
FOREACH (_tag ${SIP_TAGS})
72+
LIST(APPEND _sip_tags -t ${_tag})
73+
ENDFOREACH (_tag)
74+
75+
SET(_sip_x)
76+
FOREACH (_x ${SIP_DISABLE_FEATURES})
77+
LIST(APPEND _sip_x -x ${_x})
78+
ENDFOREACH (_x ${SIP_DISABLE_FEATURES})
79+
80+
SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}")
81+
SET(_sip_output_files)
82+
FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
83+
IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
84+
SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/sip${_child_module_name}part${CONCAT_NUM}.cpp )
85+
ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
86+
ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
87+
88+
IF(NOT WIN32)
89+
SET(TOUCH_COMMAND touch)
90+
ELSE(NOT WIN32)
91+
SET(TOUCH_COMMAND echo)
92+
# instead of a touch command, give out the name and append to the files
93+
# this is basically what the touch command does.
94+
FOREACH(filename ${_sip_output_files})
95+
FILE(APPEND ${filename} "")
96+
ENDFOREACH(filename ${_sip_output_files})
97+
ENDIF(NOT WIN32)
98+
ADD_CUSTOM_COMMAND(
99+
OUTPUT ${_sip_output_files}
100+
COMMAND ${CMAKE_COMMAND} -E echo ${message}
101+
COMMAND ${TOUCH_COMMAND} ${_sip_output_files}
102+
COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_BINARY_DIR}/${_module_path} ${_sip_includes} ${_abs_module_sip}
103+
DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND}
104+
)
105+
# not sure if type MODULE could be uses anywhere, limit to cygwin for now
106+
IF (CYGWIN)
107+
ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} )
108+
ELSE (CYGWIN)
109+
ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} )
110+
ENDIF (CYGWIN)
111+
TARGET_LINK_LIBRARIES(${_logical_name} ${PYTHON_LIBRARY})
112+
TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES})
113+
SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name})
114+
115+
IF (WIN32)
116+
SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES SUFFIX ".pyd")
117+
ENDIF (WIN32)
118+
119+
INSTALL(TARGETS ${_logical_name} DESTINATION "${PYTHON_SITE_PACKAGES_DIR}/${_parent_module_path}")
120+
121+
ENDMACRO(ADD_SIP_PYTHON_MODULE)

‎python/CMakeLists.txt

Lines changed: 69 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,71 @@
1+
12
SUBDIRS(plugins)
2-
IF (WIN32)
3-
SET(BINDINGS_CORE_LIB ${CMAKE_CURRENT_BINARY_DIR}/core/core.pyd)
4-
SET(BINDINGS_GUI_LIB ${CMAKE_CURRENT_BINARY_DIR}/gui/gui.pyd)
5-
SET(BINDINGS_ANALYSIS_LIB ${CMAKE_CURRENT_BINARY_DIR}/analysis/analysis.pyd)
6-
IF (NOT MSVC)
7-
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.dll)
8-
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.dll)
9-
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.dll)
10-
ELSE (NOT MSVC)
11-
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/${CMAKE_CFG_INTDIR}/qgis_core.lib)
12-
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/${CMAKE_CFG_INTDIR}/qgis_gui.lib)
13-
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/${CMAKE_CFG_INTDIR}/qgis_analysis.lib)
14-
ENDIF (NOT MSVC)
15-
ELSE (WIN32)
16-
SET(BINDINGS_CORE_LIB ${CMAKE_CURRENT_BINARY_DIR}/core/core.so)
17-
SET(BINDINGS_GUI_LIB ${CMAKE_CURRENT_BINARY_DIR}/gui/gui.so)
18-
SET(BINDINGS_ANALYSIS_LIB ${CMAKE_CURRENT_BINARY_DIR}/analysis/analysis.so)
19-
IF (APPLE)
20-
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.dylib)
21-
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.dylib)
22-
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.dylib)
23-
ELSE (APPLE)
24-
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.so)
25-
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.so)
26-
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.so)
27-
ENDIF (APPLE)
28-
ENDIF (WIN32)
29-
30-
SET (BINDINGS_LIBS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB} ${BINDINGS_ANALYSIS_LIB})
31-
SET (BINDINGS_CORE_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/core/Makefile)
32-
SET (BINDINGS_GUI_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/gui/Makefile)
33-
SET (BINDINGS_ANALYSIS_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/analysis/Makefile)
34-
35-
# 'python' target will force to build bindings libs for core and gui
36-
ADD_CUSTOM_TARGET (python ALL DEPENDS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB} ${BINDINGS_ANALYSIS_LIB})
37-
38-
# don't run python before the libs are built
39-
ADD_DEPENDENCIES (python qgis_core qgis_gui qgis_analysis)
40-
41-
FILE(GLOB CORE_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/core/*.sip")
42-
FILE(GLOB GUI_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gui/*.sip")
43-
FILE(GLOB ANALYSIS_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/analysis/*.sip")
44-
45-
# Step 1: during configuration
46-
# create file configure.py from configure.py.in
47-
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/configure.py.in
48-
${CMAKE_CURRENT_BINARY_DIR}/configure.py)
49-
50-
IF (MSVC)
51-
SET(EXPORT "__declspec(dllimport)")
52-
ELSE (MSVC)
53-
SET(EXPORT "")
54-
ENDIF (MSVC)
55-
56-
# Step 2: during make
57-
# run python configure.py
58-
# it will run SIP utility to generate sources and will prepare makefiles
59-
# should be run everytime core or gui library has been changed
60-
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_CORE_MAKEFILE} ${BINDINGS_GUI_MAKEFILE} ${BINDINGS_ANALYSIS_MAKEFILE} PRE_BUILD
61-
COMMAND ${PYTHON_EXECUTABLE}
62-
ARGS ${CMAKE_CURRENT_BINARY_DIR}/configure.py ${CMAKE_CFG_INTDIR} ${EXPORT}
63-
DEPENDS ${QGIS_CORE_LIB} ${QGIS_GUI_LIB} ${QGIS_ANALYSIS_LIB}
64-
${CMAKE_CURRENT_BINARY_DIR}/configure.py
65-
${CORE_SIP_FILES} ${GUI_SIP_FILES} ${ANALYSIS_SIP_FILES})
66-
67-
# Step 3: run make in core and gui subdirs
68-
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_CORE_LIB} PRE_LINK
69-
COMMAND ${SIP_MAKE_PROGRAM}
70-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/core
71-
DEPENDS ${BINDINGS_CORE_MAKEFILE})
72-
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_GUI_LIB} PRE_LINK
73-
COMMAND ${SIP_MAKE_PROGRAM}
74-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gui
75-
DEPENDS ${BINDINGS_GUI_MAKEFILE})
76-
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_ANALYSIS_LIB} PRE_LINK
77-
COMMAND ${SIP_MAKE_PROGRAM}
78-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/analysis
79-
DEPENDS ${BINDINGS_ANALYSIS_MAKEFILE})
80-
81-
IF (BINDINGS_GLOBAL_INSTALL)
82-
83-
# python's site-packages dir: bindings will be installed here
84-
IF (UNIX)
85-
SET (CMD "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")
86-
ELSE (UNIX)
87-
SET (CMD "
88-
import sys
89-
print sys.exec_prefix + '/lib/site-packages'
90-
")
91-
ENDIF (UNIX)
92-
93-
EXEC_PROGRAM(${PYTHON_EXECUTABLE} ARGS -c "\"${CMD}\"" OUTPUT_VARIABLE SITE_PKG_PATH)
94-
95-
ELSE (BINDINGS_GLOBAL_INSTALL)
96-
97-
SET (SITE_PKG_PATH ${QGIS_DATA_DIR}/python)
98-
99-
ENDIF (BINDINGS_GLOBAL_INSTALL)
100-
101-
102-
103-
# Step 4: install built libs to python's site packages
104-
INSTALL(FILES __init__.py utils.py console.py ${CMAKE_CURRENT_BINARY_DIR}/qgisconfig.py ${BINDINGS_LIBS} DESTINATION ${SITE_PKG_PATH}/qgis)
1053

4+
5+
INCLUDE_DIRECTORIES(
6+
${PYTHON_INCLUDE_PATH}
7+
${SIP_INCLUDE_DIR}
8+
${QT_QTCORE_INCLUDE_DIR}
9+
${QT_QTGUI_INCLUDE_DIR}
10+
${QT_QTNETWORK_INCLUDE_DIR}
11+
${QT_QTSVG_INCLUDE_DIR}
12+
${QT_QTXML_INCLUDE_DIR}
13+
${GDAL_INCLUDE_DIR}
14+
${GEOS_INCLUDE_DIR}
15+
16+
../src/core
17+
../src/core/composer
18+
../src/core/raster
19+
../src/core/renderer
20+
../src/core/spatialindex
21+
../src/core/symbology
22+
../src/core/symbology-ng
23+
${CMAKE_BINARY_DIR} # qgsconfig.h, qgssvnversion.h
24+
)
25+
26+
27+
# In Windef.h there are min() and max() macros that interfere with the usage
28+
# of std::numeric_limits<T>::min() and :max() in qgsrasterbands.h.
29+
IF(MSVC)
30+
ADD_DEFINITIONS(-DNOMINMAX)
31+
ENDIF(MSVC)
32+
33+
34+
# core module
35+
FILE(GLOB sip_files_core core/*.sip)
36+
set(SIP_EXTRA_FILES_DEPEND ${sip_files_core})
37+
ADD_SIP_PYTHON_MODULE(qgis.core core/core.sip qgis_core)
38+
39+
# additional gui includes
40+
INCLUDE_DIRECTORIES(
41+
../src/gui
42+
../src/gui/symbology-ng
43+
../src/plugins
44+
${CMAKE_BINARY_DIR}/src/gui
45+
${CMAKE_BINARY_DIR}/src/ui
46+
)
47+
48+
# gui module
49+
FILE(GLOB sip_files_gui gui/*.sip)
50+
set(SIP_EXTRA_FILES_DEPEND ${sip_files_gui})
51+
ADD_SIP_PYTHON_MODULE(qgis.gui gui/gui.sip qgis_core qgis_gui)
52+
53+
# additional analysis includes
54+
INCLUDE_DIRECTORIES(
55+
../src/analysis/vector
56+
${CMAKE_BINARY_DIR}/src/analysis/vector
57+
)
58+
59+
# analysis module
60+
FILE(GLOB sip_files_analysis analysis/*.sip)
61+
set(SIP_EXTRA_FILES_DEPEND ${sip_files_analysis})
62+
ADD_SIP_PYTHON_MODULE(qgis.analysis analysis/analysis.sip qgis_core qgis_analysis)
63+
64+
65+
SET (QGIS_PYTHON_DIR ${PYTHON_SITE_PACKAGES_DIR}/qgis)
66+
67+
ADD_CUSTOM_TARGET(compile_python_files ALL)
68+
69+
PYTHON_INSTALL(__init__.py ${QGIS_PYTHON_DIR})
70+
PYTHON_INSTALL(utils.py ${QGIS_PYTHON_DIR})
71+
PYTHON_INSTALL(console.py ${QGIS_PYTHON_DIR})

‎python/configure.py.in

Lines changed: 0 additions & 213 deletions
This file was deleted.

‎python/qgisconfig.py.in

Lines changed: 0 additions & 40 deletions
This file was deleted.

‎src/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
SUBDIRS(core analysis ui gui app providers plugins helpviewer)
33

4-
IF (HAVE_PYTHON AND WITH_BINDINGS)
4+
IF (WITH_BINDINGS)
55
SUBDIRS(python)
6-
ENDIF (HAVE_PYTHON AND WITH_BINDINGS)
6+
ENDIF (WITH_BINDINGS)
77

88
IF (APPLE)
99
SUBDIRS(mac)

0 commit comments

Comments
 (0)
Please sign in to comment.