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 behavior 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# SIP_BUILD_EXTRA_OPTIONS - Extra command line options which should be passed on to 39# sip-build. 40 41SET(SIP_INCLUDES) 42SET(SIP_TAGS) 43SET(SIP_CONCAT_PARTS 16) 44SET(SIP_DISABLE_FEATURES) 45SET(SIP_EXTRA_OPTIONS) 46SET(SIP_EXTRA_OBJECTS) 47SET(SIP_BUILD_EXTRA_OPTIONS) 48 49MACRO(GENERATE_SIP_PYTHON_MODULE_CODE MODULE_NAME MODULE_SIP SIP_FILES CPP_FILES) 50 51 STRING(REPLACE "." "/" _x ${MODULE_NAME}) 52 GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH) 53 GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME) 54 GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH) 55 GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE) 56 57 # If this is not need anymore (using input configuration file for SIP files) 58 # SIP could be run in the source rather than in binary directory 59 SET(_configured_module_sip ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/${_module_path}.sip) 60 FOREACH (_sip_file ${SIP_FILES}) 61 GET_FILENAME_COMPONENT(_sip_file_path ${_sip_file} PATH) 62 GET_FILENAME_COMPONENT(_sip_file_name_we ${_sip_file} NAME_WE) 63 FILE(RELATIVE_PATH _sip_file_relpath ${CMAKE_CURRENT_SOURCE_DIR} "${_sip_file_path}/${_sip_file_name_we}") 64 SET(_out_sip_file "${CMAKE_CURRENT_BINARY_DIR}/${_sip_file_relpath}.sip") 65 CONFIGURE_FILE(${_sip_file} ${_out_sip_file}) 66 ENDFOREACH (_sip_file) 67 68 SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}") 69 SET(_sip_output_files) 70 71 # Suppress warnings 72 IF(PEDANTIC) 73 IF(MSVC) 74 ADD_DEFINITIONS( 75 /wd4189 # local variable is initialized but not referenced 76 /wd4996 # deprecation warnings (bindings re-export deprecated methods) 77 /wd4701 # potentially uninitialized variable used (sip generated code) 78 /wd4702 # unreachable code (sip generated code) 79 /wd4703 # potentially uninitialized local pointer variable 'sipType' used 80 ) 81 ELSE(MSVC) 82 # disable all warnings 83 ADD_DEFINITIONS( -w -Wno-deprecated-declarations ) 84 IF(NOT APPLE) 85 ADD_DEFINITIONS( -fpermissive ) 86 ENDIF(NOT APPLE) 87 ENDIF(MSVC) 88 ENDIF(PEDANTIC) 89 90 IF(MSVC) 91 ADD_DEFINITIONS( /bigobj ) 92 ENDIF(MSVC) 93 94 IF (SIP_BUILD_EXECUTABLE) 95 96 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/build/${_child_module_name}) # Output goes in this dir. 97 98 FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) 99 IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) 100 SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/build/${_child_module_name}/sip${_child_module_name}part${CONCAT_NUM}.cpp ) 101 ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) 102 ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) 103 104 SET(SIPCMD ${SIP_BUILD_EXECUTABLE} --no-protected-is-public --pep484-pyi --no-make --concatenate=${SIP_CONCAT_PARTS} --qmake=${QMAKE_EXECUTABLE} --include-dir=${CMAKE_CURRENT_BINARY_DIR} --include-dir=${PYQT5_SIP_DIR} ${SIP_BUILD_EXTRA_OPTIONS}) 105 106 ADD_CUSTOM_COMMAND( 107 OUTPUT ${_sip_output_files} 108 COMMAND ${CMAKE_COMMAND} -E echo ${message} 109 COMMAND ${SIPCMD} 110 COMMAND ${CMAKE_COMMAND} -E touch ${_sip_output_files} 111 WORKING_DIRECTORY ${_module_path} 112 MAIN_DEPENDENCY ${_configured_module_sip} 113 DEPENDS ${SIP_EXTRA_FILES_DEPEND} 114 VERBATIM 115 ) 116 117 ELSE (SIP_BUILD_EXECUTABLE) 118 119 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}) # Output goes in this dir. 120 121 SET(_sip_includes) 122 FOREACH (_inc ${SIP_INCLUDES}) 123 GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE) 124 LIST(APPEND _sip_includes -I ${_abs_inc}) 125 ENDFOREACH (_inc ) 126 127 SET(_sip_tags) 128 FOREACH (_tag ${SIP_TAGS}) 129 LIST(APPEND _sip_tags -t ${_tag}) 130 ENDFOREACH (_tag) 131 132 SET(_sip_x) 133 FOREACH (_x ${SIP_DISABLE_FEATURES}) 134 LIST(APPEND _sip_x -x ${_x}) 135 ENDFOREACH (_x ${SIP_DISABLE_FEATURES}) 136 137 FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) 138 IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) 139 SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/sip${_child_module_name}part${CONCAT_NUM}.cpp ) 140 ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) 141 ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) 142 143 SET(SIPCMD ${SIP_BINARY_PATH} ${_sip_tags} -w -e ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_BINARY_DIR}/${_module_path} -I ${CMAKE_CURRENT_BINARY_DIR}/${_module_path} ${_sip_includes} ${_configured_module_sip}) 144 ADD_CUSTOM_COMMAND( 145 OUTPUT ${_sip_output_files} 146 COMMAND ${CMAKE_COMMAND} -E echo ${message} 147 COMMAND ${CMAKE_COMMAND} -E touch ${_sip_output_files} 148 COMMAND ${SIPCMD} 149 MAIN_DEPENDENCY ${_configured_module_sip} 150 DEPENDS ${SIP_EXTRA_FILES_DEPEND} 151 VERBATIM 152 ) 153 154 ENDIF (SIP_BUILD_EXECUTABLE) 155 156 ADD_CUSTOM_TARGET(generate_sip_${MODULE_NAME}_cpp_files DEPENDS ${_sip_output_files}) 157 158 SET(CPP_FILES ${sip_output_files}) 159ENDMACRO(GENERATE_SIP_PYTHON_MODULE_CODE) 160 161# Will compile and link the module 162MACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS) 163 SET(EXTRA_LINK_LIBRARIES ${ARGN}) 164 165 # We give this target a long logical target name. 166 # (This is to avoid having the library name clash with any already 167 # install library names. If that happens then cmake dependency 168 # tracking get confused.) 169 STRING(REPLACE "." "_" _logical_name ${MODULE_NAME}) 170 SET(_logical_name "python_module_${_logical_name}") 171 GET_FILENAME_COMPONENT(_module_path ${SIP_FILES} PATH) 172 173 ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} ${EXTRA_OBJECTS}) 174 SET_PROPERTY(TARGET ${_logical_name} PROPERTY AUTOMOC OFF) 175 TARGET_INCLUDE_DIRECTORIES(${_logical_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/build) 176 177 IF (${SIP_VERSION_STR} VERSION_LESS 5.0.0) 178 # require c++14 only -- sip breaks with newer versions due to reliance on throw(...) annotations removed in c++17 179 TARGET_COMPILE_FEATURES(${_logical_name} PRIVATE cxx_std_14) 180 ENDIF (${SIP_VERSION_STR} VERSION_LESS 5.0.0) 181 182 SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES CXX_VISIBILITY_PRESET default) 183 IF (NOT APPLE) 184 TARGET_LINK_LIBRARIES(${_logical_name} ${Python_LIBRARIES}) 185 ENDIF (NOT APPLE) 186 TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES}) 187 IF (APPLE) 188 SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") 189 ENDIF (APPLE) 190 SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name}) 191 192 IF (WIN32) 193 SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES SUFFIX ".pyd") 194 GET_TARGET_PROPERTY(_runtime_output ${_logical_name} RUNTIME_OUTPUT_DIRECTORY) 195 ADD_CUSTOM_COMMAND(TARGET ${_logical_name} POST_BUILD 196 COMMAND ${CMAKE_COMMAND} -E echo "Copying extension ${_child_module_name}" 197 COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:${_logical_name}>" "${_runtime_output}/${_child_module_name}.pyd" 198 DEPENDS ${_logical_name} 199 ) 200 ENDIF(WIN32) 201 202 INSTALL(TARGETS ${_logical_name} DESTINATION "${Python_SITEARCH}/${_parent_module_path}") 203ENDMACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS) 204