1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
SET(PYTHON_VERSION_NO_DOT ${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
SET(PYTHON_VERSION ${Python_VERSION_MAJOR}.${Python_VERSION_MINOR})
SET(TulipPythonModulesInstallDir ${CMAKE_INSTALL_PREFIX}/${TulipLibInstallDir}/tulip/python)
MACRO(TULIP_DISABLE_COMPILER_WARNINGS_PYTHON)
TULIP_SET_CXX_COMPILER_FLAG("-Wno-old-style-cast -Wno-deprecated-copy -Wno-unused-variable -Wno-overloaded-virtual -Wno-missing-field-initializers")
TULIP_SET_C_COMPILER_FLAG("-Wno-old-style-cast -Wno-deprecated-copy -Wno-unused-variable -Wno-overloaded-virtual -Wno-missing-field-initializers")
ENDMACRO(TULIP_DISABLE_COMPILER_WARNINGS_PYTHON)
GET_FILENAME_COMPONENT(PYTHON_HOME_PATH ${Python_EXECUTABLE} DIRECTORY)
# Ensure the detection of Python library installed through a bundle downloaded from Python.org or through a macports installation
IF(APPLE)
IF(NOT "${Python_EXECUTABLE}" MATCHES "^/usr/bin/python.*$")
EXECUTE_PROCESS(COMMAND bash -c "cd ${PYTHON_HOME_PATH}/.. > /dev/null; echo -n $(pwd)" OUTPUT_VARIABLE PYTHON_DIR_PATH)
SET(CMAKE_PREFIX_PATH ${PYTHON_HOME_PATH}/.. ${CMAKE_PREFIX_PATH})
ENDIF()
ENDIF(APPLE)
# Ensure headers correspond to the ones associated to the detected Python library on MacOS
IF(APPLE AND NOT "${Python_EXECUTABLE}" MATCHES "^/usr/bin/python.*$"
AND EXISTS ${PYTHON_HOME_PATH}/../Headers)
SET(Python_INCLUDE_DIRS ${PYTHON_HOME_PATH}/../Headers CACHE PATH "" FORCE)
ENDIF()
SET(SIP_BUILD ${Python_EXECUTABLE} -m sipbuild.tools.build) #instead of sip-build
SET(SIP_MODULE_PROG ${Python_EXECUTABLE} -m sipbuild.tools.module) #instead of sip-module
SET(SIP_VERSION 6.9.1)
#check if sip is installed (it is up to the user to install it)
#use the detected python interpreter to call sip instead of the command line tool
#to be sure to use the correct version (command line tool may not be in the PATH)
execute_process(
COMMAND ${SIP_BUILD} --version
RESULT_VARIABLE EXIT_CODE
OUTPUT_QUIET
)
if (NOT ${EXIT_CODE} EQUAL 0)
message(FATAL_ERROR
"The \"sip\" Python package is not installed. Please install it using a command like this one: \"${Python_EXECUTABLE} -m pip install sip\".")
endif()
#check sip version
EXECUTE_PROCESS(COMMAND ${SIP_BUILD} --version OUTPUT_VARIABLE SIP_MODULE_OUTPUT)
STRING(STRIP ${SIP_MODULE_OUTPUT} SIP_MODULE_OUTPUT)
IF(${SIP_MODULE_OUTPUT} VERSION_GREATER_EQUAL ${SIP_VERSION})
MESSAGE(STATUS "Found SIP version ${SIP_MODULE_OUTPUT}")
ELSE()
MESSAGE(FATAL_ERROR "SIP Python package at least version ${SIP_VERSION} not found (found ${SIP_MODULE_OUTPUT}).")
ENDIF()
##########################################################
IF(TULIP_ACTIVATE_PYTHON_WHEEL_TARGET)
# STRING(REGEX REPLACE "[^0-9.]" "" TULIP_PYTHON_WHEEL_VERSION "${Tulip_VERSION}")
SET(TULIP_PYTHON_WHEEL_NAME tulip-python)
string(REPLACE "-" "_" TULIP_PYTHON_WHEEL_NAME_ ${TULIP_PYTHON_WHEEL_NAME})
IF(WIN32)
SET(WHEEL_INSTALL_PATH "\\")
ELSE(WIN32)
SET(WHEEL_INSTALL_PATH "/")
ENDIF(WIN32)
#check for build
execute_process(
COMMAND ${Python_EXECUTABLE} -m pip show build
RESULT_VARIABLE EXIT_CODE
OUTPUT_QUIET
)
if (NOT ${EXIT_CODE} EQUAL 0)
message(FATAL_ERROR
"The \"build\" Python package is not installed. Please install it using a command like this one: \"${Python_EXECUTABLE} -m pip install build\".")
endif()
ADD_CUSTOM_TARGET(wheel
COMMAND ${Python_EXECUTABLE} -m build --wheel
WORKING_DIRECTORY ${TULIP_PYTHON_ROOT_FOLDER})
IF(LINUX)
#where to put wheel after having it repaired
IF(NOT TULIP_WHEELS_PREFIX)
SET(TULIP_WHEELS_PREFIX ./dist)
ENDIF()
#check for auditwheel (installed by default on manylinux)
find_program(AUDITWHEEL_CMD auditwheel REQUIRED)
#filename under linux does not implement Python_SOABI well => cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-linux_x86_64 instead of cpython-${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-x86_64-linux-gnu
SET(TULIP_PYTHON_WHEEL_FILE ${TULIP_PYTHON_WHEEL_NAME_}-${Tulip_VERSION}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-linux_x86_64.whl)
ADD_CUSTOM_COMMAND(TARGET wheel POST_BUILD
COMMAND bash -xc "LD_LIBRARY_PATH=${Qhull_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${AUDITWHEEL_CMD} repair -L native -w ${TULIP_WHEELS_PREFIX} ./dist/${TULIP_PYTHON_WHEEL_FILE}"
WORKING_DIRECTORY ${TULIP_PYTHON_ROOT_FOLDER}
COMMENT "Repairing tulip-core wheel" VERBATIM)
ENDIF(LINUX)
GET_FILENAME_COMPONENT(PYTHON_EXE_PATH ${Python_EXECUTABLE} DIRECTORY)
EXECUTE_PROCESS(COMMAND ${Python_EXECUTABLE} -m site --user-base OUTPUT_VARIABLE USER_EXE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
IF(LINUX OR APPLE)
SET(USER_EXE_PATH "${USER_EXE_PATH}/bin")
ELSE()
SET(USER_EXE_PATH "${USER_EXE_PATH}/../Scripts")
SET(PYTHON_EXE_PATH "${PYTHON_EXE_PATH}/Scripts")
ENDIF()
IF(WIN32)
find_program(DELVEWHEEL_CMD delvewheel HINTS ${USER_EXE_PATH} ${PYTHON_EXE_PATH} REQUIRED)
FILE(TO_NATIVE_PATH "${TULIP_WHEELS_PREFIX}" TULIP_WHEELS_PREFIX)
SET(TULIP_PYTHON_WHEEL_FILE ${TULIP_PYTHON_WHEEL_NAME_}-${Tulip_VERSION}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-${Python_SOABI}.whl)
ADD_CUSTOM_COMMAND(TARGET wheel POST_BUILD
#ignore-existing parameter below is important to tell delvewheel to not consider libtulip-core-x.dll
COMMAND ${DELVEWHEEL_CMD} repair -v --ignore-existing --add-path=${TULIP_PYTHON_NATIVE_FOLDER} --wheel-dir=${TULIP_WHEELS_PREFIX} ./dist/${TULIP_PYTHON_WHEEL_FILE}
WORKING_DIRECTORY ${TULIP_PYTHON_ROOT_FOLDER}
COMMENT "Repairing tulip-core wheel" VERBATIM)
ENDIF(WIN32)
IF(APPLE)
find_program(DELOCATE delocate-wheel HINTS ${USER_EXE_PATH} ${PYTHON_EXE_PATH} REQUIRED)
FILE(TO_NATIVE_PATH "${TULIP_WHEELS_PREFIX}" TULIP_WHEELS_PREFIX)
# as the built wheel is not an "universal2" wheel, it has to be renamed
# with the architecture used by the current build, before repairing
IF (CMAKE_OSX_ARCHITECTURES)
SET(ARCH ${CMAKE_OSX_ARCHITECTURES})
ELSE()
EXECUTE_PROCESS(COMMAND uname -m
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE ARCH)
ENDIF()
EXECUTE_PROCESS(COMMAND sw_vers -productVersion
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE MACOS_VERSION)
STRING(REGEX MATCH "^[0-9]+\.[0-9]+" MACOS_VERSION ${MACOS_VERSION})
STRING(REPLACE "." "_" MACOS_VERSION ${MACOS_VERSION})
SET(TULIP_PYTHON_WHEEL_FILE ${TULIP_PYTHON_WHEEL_NAME_}-${Tulip_VERSION}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-macosx_${MACOS_VERSION}_${ARCH}.whl)
ADD_CUSTOM_COMMAND(TARGET wheel POST_BUILD
COMMAND bash -c -x "mv ./dist/${TULIP_PYTHON_WHEEL_NAME_}-${Tulip_VERSION}-cp${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-*.whl ./dist/${TULIP_PYTHON_WHEEL_FILE}"
COMMAND ${DELOCATE} ./dist/${TULIP_PYTHON_WHEEL_FILE} -w ${TULIP_WHEELS_PREFIX}
WORKING_DIRECTORY ${TULIP_PYTHON_ROOT_FOLDER}
COMMENT "Repairing tulip-core wheel" VERBATIM)
ENDIF(APPLE)
ENDIF(TULIP_ACTIVATE_PYTHON_WHEEL_TARGET)
##########################################################
#generate the sip module sources
SET(SIP_MODULE tulip.native.sip)
string(REPLACE "." "_" SIP_MODULE_ ${SIP_MODULE})
SET(SIP_LIB sip)
SET(SIP_INCLUDE_DIR ${PROJECT_BINARY_DIR}/thirdparty/sip)
FILE(MAKE_DIRECTORY ${SIP_INCLUDE_DIR})
execute_process(
COMMAND ${SIP_MODULE_PROG} --sdist --target-dir=${SIP_INCLUDE_DIR} ${SIP_MODULE}
COMMAND_ERROR_IS_FATAL ANY)
FILE(GLOB SIP_DIST LIST_DIRECTORIES false CONFIGURE_DEPENDS ${SIP_INCLUDE_DIR}/${SIP_MODULE_}-*.tar.gz)
STRING(REGEX MATCH "[0-9][0-9]+\.[0-9]+\.[0-9]+" SIP_API_FULL ${SIP_DIST})
STRING(REGEX MATCH "^[0-9]+\.[0-9]+" SIP_API ${SIP_API_FULL}) #used in pyproject.toml files
FILE(ARCHIVE_EXTRACT INPUT ${SIP_DIST} DESTINATION ${SIP_INCLUDE_DIR} PATTERNS *.c *.h)
SET (SIP_H_DIR ${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL})
#######################
#compile the sip module on our own instead of pip (produce faulty binaries on Windows and module is not compiled with gcc)
SET(SIP_PYTHON_MODULE_SRC
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_array.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_core.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_enum.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_descriptors.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_int_convertors.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_object_map.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_threads.c
${SIP_INCLUDE_DIR}/${SIP_MODULE_}-${SIP_API_FULL}/sip_voidptr.c
)
Python_add_library(${SIP_LIB} MODULE WITH_SOABI ${SIP_PYTHON_MODULE_SRC})
target_include_directories(${SIP_LIB} PUBLIC ${Python_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES COMPILE_OPTIONS -w)
TARGET_COMPILE_DEFINITIONS(${SIP_LIB} PUBLIC "DYNAMIC_ANNOTATIONS_ENABLED=1")
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${TULIP_PYTHON_NATIVE_FOLDER})
SET_TARGET_PROPERTIES(${SIP_LIB} PROPERTIES OUTPUT_NAME sip)
IF(TULIP_ACTIVATE_PYTHON_WHEEL_TARGET)
ADD_DEPENDENCIES(wheel ${SIP_LIB})
ENDIF(TULIP_ACTIVATE_PYTHON_WHEEL_TARGET)
TULIP_INSTALL_PYTHON_FILES(tulip/native ${SIP_LIB})
|