Spaces:
Sleeping
Sleeping
| # Useful references: | |
| # https://thomastrapp.com/blog/building-a-pypi-package-for-a-modern-cpp-project/ for reference | |
| # https://www.benjack.io/2017/06/12/python-cpp-tests.html also interesting | |
| # https://www.python.org/dev/peps/pep-0427/ the official package format description | |
| set(_MAKE_PYTHON_WHEEL_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}") | |
| function( MakeWheel python_module) | |
| cmake_parse_arguments(MAKEWHEEL "PRINT_HELP" "MODULE;VERSION;SUMMARY;DESCRIPTION;HOMEPAGE;AUTHOR;EMAIL;LICENCE" "REQUIRES" ${ARGN} ) | |
| set(version ${MAKEWHEEL_VERSION}) | |
| execute_process( | |
| COMMAND ${Python_EXECUTABLE} -c " | |
| from setuptools.dist import Distribution | |
| from setuptools import Extension | |
| def wheel_name(**kwargs): | |
| # create a fake distribution from arguments | |
| dist = Distribution(attrs=kwargs) | |
| # finalize bdist_wheel command | |
| bdist_wheel_cmd = dist.get_command_obj('bdist_wheel') | |
| bdist_wheel_cmd.ensure_finalized() | |
| # assemble wheel file name | |
| distname = bdist_wheel_cmd.wheel_dist_name | |
| tag = '-'.join(bdist_wheel_cmd.get_tag()) | |
| return f'{distname};{tag}' | |
| print(wheel_name(name='${python_module}', version='${version}', ext_modules=[Extension('dummy', ['summy.c'])])) | |
| " | |
| OUTPUT_VARIABLE wheel_filename | |
| OUTPUT_STRIP_TRAILING_WHITESPACE | |
| ERROR_QUIET | |
| ) | |
| if(NOT wheel_filename) | |
| message(STATUS "Python module `setuptools` required for correct wheel filename generation. Please install if needed.") | |
| set(wheel_filename "unknown;unknown") | |
| endif() | |
| list(GET wheel_filename 0 distname) | |
| list(GET wheel_filename 1 platformtag) | |
| set(complete_tag "${distname}-${platformtag}") | |
| set(wheel_filename "${CMAKE_BINARY_DIR}/${complete_tag}.whl") | |
| set(wheel_distinfo "${CMAKE_BINARY_DIR}/${python_module}-${version}.dist-info") | |
| set(wheel_data "${CMAKE_BINARY_DIR}/${python_module}-${version}.data") | |
| set(wheel_generator_string "pango_wheelgen_${version}") | |
| if( MAKEWHEEL_REQUIRES ) | |
| set(MAKEWHEEL_REQUIRES "Requires-Dist: ${MAKEWHEEL_REQUIRES}") | |
| string(REPLACE ";" "\nRequires-Dist: " MAKEWHEEL_REQUIRES "${MAKEWHEEL_REQUIRES}") | |
| endif() | |
| ########################################## | |
| ## Create dist info folder | |
| file(GLOB wheel_info_files "${_MAKE_PYTHON_WHEEL_LIST_DIR}/wheel-dist-info/*" ) | |
| file(WRITE "${wheel_distinfo}/RECORD" "") | |
| foreach(template_path ${wheel_info_files}) | |
| get_filename_component(template_name "${template_path}" NAME) | |
| configure_file( ${template_path} "${wheel_distinfo}/${template_name}" ) | |
| file(SHA256 "${template_path}" file_sha) | |
| file (SIZE "${template_path}" file_size) | |
| file(APPEND "${wheel_distinfo}/RECORD" "${python_module}-${version}.dist-info/${template_name},sha256=${file_sha},${file_size}\n") | |
| endforeach() | |
| # TODO: Add line in RECORD for .so module itself (needs to be build time) | |
| ########################################## | |
| ## Place module into data folder | |
| set_target_properties( ${python_module} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${wheel_data}/purelib") | |
| ########################################## | |
| ## Rule for creating file wheel zip | |
| add_custom_command( | |
| OUTPUT ${wheel_filename} | |
| DEPENDS ${python_module} | |
| COMMAND ${CMAKE_COMMAND} -E tar cf ${wheel_filename} --format=zip -- ${wheel_distinfo} ${wheel_data} | |
| COMMENT "Creating Wheel ${wheel_filename}" | |
| VERBATIM | |
| ) | |
| ########################################## | |
| ## Create a friendlier target name we can refer to | |
| add_custom_target("${python_module}_wheel" DEPENDS "${wheel_filename}") | |
| add_custom_target( | |
| "${python_module}_pip_install" | |
| DEPENDS "${python_module}_wheel" | |
| COMMAND ${Python_EXECUTABLE} -mpip install "${wheel_filename}" --force-reinstall | |
| COMMENT "Installing for selected Python '${Python_EXECUTABLE}'" | |
| ) | |
| add_custom_target( | |
| "${python_module}_pip_uninstall" | |
| COMMAND ${Python_EXECUTABLE} -mpip uninstall -y ${python_module} | |
| ) | |
| ########################################## | |
| ## Help message since this is tricky for people | |
| if(MAKEWHEEL_PRINT_HELP) | |
| message(STATUS "Selected Python: '${Python_EXECUTABLE}'. cmake --build . -t ${python_module}_pip_install to use ${python_module} module.") | |
| endif() | |
| endfunction() | |